From patchwork Thu Aug 29 23:29:08 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 11122583 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 839C014E5 for ; Thu, 29 Aug 2019 23:29:44 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 613082173E for ; Thu, 29 Aug 2019 23:29:44 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="GirbosQq" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1725844AbfH2X3n (ORCPT ); Thu, 29 Aug 2019 19:29:43 -0400 Received: from sonic303-28.consmr.mail.ne1.yahoo.com ([66.163.188.154]:44603 "EHLO sonic303-28.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725826AbfH2X3n (ORCPT ); Thu, 29 Aug 2019 19:29:43 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1567121379; bh=TtO2nzJIQBSCQoTzcHeM4Y71S+gjhNW1YC/ivUODDTk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=GirbosQqtABNbnXVO+Bjxmnxyi4xVrl7h2g1/vrpsCDeC1tG2ykbGFSoAIx5hlTfvM2HPYs+2beGaTNFRL3Ht/uH6RyxUigySpTs6DOWfMu0TSzXF51wTws5AchB3+1zGWSwYWvsbU9PK0xjVd7SOn1HrRJ8ypzomV5nHL1RtGvgviUXcrsCBhYr8sjGNMT0PVTy1xWarg9vxrSi9OKo+RFWTq9RIwWWlXPNaGtYknPLS0LKuNI774kbkeb1I81C56Xubk+/YwypL4QUJcY1HpgOWmuZM99JC+1UGzzDtHby698bP/RC0N0HVFuxM4q8wx9uTYgkpJzCBjhCO/WzLg== X-YMail-OSG: Zq2EOfoVM1lZo7zVEqP0ABdWfydffRCft8w1CpL1j.IjsNepSNcxGoFCpC_n5ln XOMRRWQB56.HLbbyxcU2c_lzAJCnlK5xDRZHo.lbdXynl2OBHMkyfkONLTC6cHYWqQMsYTDpObNy oW.4hkn2NRq5FXVxoA3.Erqd2K2LiTnkyYUjhAUM1YuHZZmwKJocZeL6asdtTsHihHs8LPymsXSg zpyLvYUbfW8Q9j2EVonpbaXDwYjgbok60GT6RQ71Q_Z.AzGv3J.Ha0EzKD4VrYMGmhHQhVuyI8FQ _CkK3220It3JPfGYiuBvQEDfzcvz33gI272RljdVY_A4FRDjpxFTCksrMFKdXHAphC9cndlIeEhE iDcJAAHgyu7HRWyxARIEiu4l6VfUfDeHSbuv3tUZU4yI4ewShZk0gX7fH79TZQQWwBqq3QqXcUjN mj8n0j7BZLbcxus1of9YWfrvZBCuDBKj6MLY5PCIvqejGzaF7JQ1TTQi4fgCDsfG3kd3z6RYuz7H 2yxCFBFYsT8lgFNrJXYwddIPqxUR80owBGLEXCGCd6iP57OA8abIgoRpPsGZQQqpS0K0BYwxbD0O i2OACNtcudeek9tO6tD9V_G6HCcPJ9Y7IJiX2VrEXtwsjQ8jjc95L5KmT.ISiV91rz_dGWOOMcfb h1SYGAxPnsU3cx9bBHI7SvTvsIHjai08JdjGbCTgsooeIBirVlYw.mCd0SbTrw9OGArVzpjmPEFk 9i0n3Pnr_EZyjgTq1QuLglM4kuZJySq_xrdYlA1TK9BjxCW2UAHu8cXcHbzl1t0gSDPy1qzbbtG. fhFIqrvX5OkM9fIWjI02Jd7MPK5rW5mNRCwxV1KdsPUfvWMnh3XWAYpjdwEY9ZLQkp.f8NVlHD94 8QgOJR8.j8QpA.h2u9qYYNkvRqVAWlKFxE.VvqvPXBLG5sNwlCnU1LBzg7km.eL_rQwNH1XPL0VT SdxyNzA_zWA5.f6s4XVKWiLNFu582LNg8Y4CBgQALPv2pUiIs6yBU0XITKtG7ScEjOX3J2zFkCQ1 GCQBxCa2D9Fbcgb4o82V_AovGyQ8CNxfRCpU3MRvQef07XT.EzIqSdiakYhNVBY73LxnzTnBE_eB UxWcinYZuPP3cVFknxpnEOqaXHee0HiYfS4qFOzK_2mTJownvsZcECbVfUAF5KSucvFVWHiJw9KQ FD1amDluRxfkuF3RSvM62Dwu3LwGGjpv1B1v6zwu.4GtAdlRASl9hJnYnRKsiXNI1iZj21SOXSIi lmfOhAS4ODMOyaj56zYVfSQBTimvD57HfOjgXM3sUcp9JSUES9ije5zFgyq9LothVPZl3lrhDdVA sppMJuIaQ Received: from sonic.gate.mail.ne1.yahoo.com by sonic303.consmr.mail.ne1.yahoo.com with HTTP; Thu, 29 Aug 2019 23:29:39 +0000 Received: by smtp403.mail.ne1.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID 348e1bb830015a550a7ef552e960420a; Thu, 29 Aug 2019 23:29:38 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, jmorris@namei.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org Cc: casey@schaufler-ca.com, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, paul@paul-moore.com, sds@tycho.nsa.gov Subject: [PATCH v8 01/28] LSM: Infrastructure management of the superblock Date: Thu, 29 Aug 2019 16:29:08 -0700 Message-Id: <20190829232935.7099-2-casey@schaufler-ca.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190829232935.7099-1-casey@schaufler-ca.com> References: <20190829232935.7099-1-casey@schaufler-ca.com> MIME-Version: 1.0 Sender: selinux-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: selinux@vger.kernel.org Move management of the superblock->sb_security blob out of the individual security modules and into the security infrastructure. Instead of allocating the blobs from within the modules the modules tell the infrastructure how much space is required, and the space is allocated there. Reviewed-by: Kees Cook Reviewed-by: John Johansen Signed-off-by: Casey Schaufler Reviewed-by: Stephen Smalley --- include/linux/lsm_hooks.h | 1 + security/security.c | 46 ++++++++++++++++++++---- security/selinux/hooks.c | 58 ++++++++++++------------------- security/selinux/include/objsec.h | 6 ++++ security/selinux/ss/services.c | 3 +- security/smack/smack.h | 6 ++++ security/smack/smack_lsm.c | 35 +++++-------------- 7 files changed, 85 insertions(+), 70 deletions(-) diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h index a240a3fc5fc4..f9222a04968d 100644 --- a/include/linux/lsm_hooks.h +++ b/include/linux/lsm_hooks.h @@ -2047,6 +2047,7 @@ struct lsm_blob_sizes { int lbs_cred; int lbs_file; int lbs_inode; + int lbs_superblock; int lbs_ipc; int lbs_msg_msg; int lbs_task; diff --git a/security/security.c b/security/security.c index 23cbb1a295a3..86198e303203 100644 --- a/security/security.c +++ b/security/security.c @@ -172,6 +172,7 @@ static void __init lsm_set_blob_sizes(struct lsm_blob_sizes *needed) lsm_set_blob_size(&needed->lbs_inode, &blob_sizes.lbs_inode); lsm_set_blob_size(&needed->lbs_ipc, &blob_sizes.lbs_ipc); lsm_set_blob_size(&needed->lbs_msg_msg, &blob_sizes.lbs_msg_msg); + lsm_set_blob_size(&needed->lbs_superblock, &blob_sizes.lbs_superblock); lsm_set_blob_size(&needed->lbs_task, &blob_sizes.lbs_task); } @@ -300,12 +301,13 @@ static void __init ordered_lsm_init(void) for (lsm = ordered_lsms; *lsm; lsm++) prepare_lsm(*lsm); - init_debug("cred blob size = %d\n", blob_sizes.lbs_cred); - init_debug("file blob size = %d\n", blob_sizes.lbs_file); - init_debug("inode blob size = %d\n", blob_sizes.lbs_inode); - init_debug("ipc blob size = %d\n", blob_sizes.lbs_ipc); - init_debug("msg_msg blob size = %d\n", blob_sizes.lbs_msg_msg); - init_debug("task blob size = %d\n", blob_sizes.lbs_task); + init_debug("cred blob size = %d\n", blob_sizes.lbs_cred); + init_debug("file blob size = %d\n", blob_sizes.lbs_file); + init_debug("inode blob size = %d\n", blob_sizes.lbs_inode); + init_debug("ipc blob size = %d\n", blob_sizes.lbs_ipc); + init_debug("msg_msg blob size = %d\n", blob_sizes.lbs_msg_msg); + init_debug("superblock blob size = %d\n", blob_sizes.lbs_superblock); + init_debug("task blob size = %d\n", blob_sizes.lbs_task); /* * Create any kmem_caches needed for blobs @@ -603,6 +605,27 @@ static void __init lsm_early_task(struct task_struct *task) panic("%s: Early task alloc failed.\n", __func__); } +/** + * 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. + */ +static int lsm_superblock_alloc(struct super_block *sb) +{ + if (blob_sizes.lbs_superblock == 0) { + sb->s_security = NULL; + 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. * @@ -776,12 +799,21 @@ int security_fs_context_parse_param(struct fs_context *fc, struct fs_parameter * int security_sb_alloc(struct super_block *sb) { - return call_int_hook(sb_alloc_security, 0, sb); + int rc = lsm_superblock_alloc(sb); + + if (unlikely(rc)) + return rc; + rc = call_int_hook(sb_alloc_security, 0, sb); + if (unlikely(rc)) + security_sb_free(sb); + return rc; } void security_sb_free(struct super_block *sb) { call_void_hook(sb_free_security, sb); + kfree(sb->s_security); + sb->s_security = NULL; } void security_free_mnt_opts(void **mnt_opts) diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 1d0b37af2444..7478d8eda00a 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -335,7 +335,7 @@ static void inode_free_security(struct inode *inode) if (!isec) return; - sbsec = inode->i_sb->s_security; + sbsec = selinux_superblock(inode->i_sb); /* * As not all inode security structures are in a list, we check for * empty list outside of the lock to make sure that we won't waste @@ -366,11 +366,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); @@ -379,18 +375,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 = sb->s_security; - sb->s_security = NULL; - kfree(sbsec); -} - struct selinux_mnt_opts { const char *fscontext, *context, *rootcontext, *defcontext; }; @@ -507,7 +495,7 @@ static int selinux_is_genfs_special_handling(struct super_block *sb) static int selinux_is_sblabel_mnt(struct super_block *sb) { - struct superblock_security_struct *sbsec = sb->s_security; + struct superblock_security_struct *sbsec = selinux_superblock(sb); /* * IMPORTANT: Double-check logic in this function when adding a new @@ -535,7 +523,7 @@ static int selinux_is_sblabel_mnt(struct super_block *sb) static int sb_finish_set_opts(struct super_block *sb) { - struct superblock_security_struct *sbsec = sb->s_security; + struct superblock_security_struct *sbsec = selinux_superblock(sb); struct dentry *root = sb->s_root; struct inode *root_inode = d_backing_inode(root); int rc = 0; @@ -648,7 +636,7 @@ static int selinux_set_mnt_opts(struct super_block *sb, unsigned long *set_kern_flags) { const struct cred *cred = current_cred(); - struct superblock_security_struct *sbsec = sb->s_security; + struct superblock_security_struct *sbsec = selinux_superblock(sb); struct dentry *root = sbsec->sb->s_root; struct selinux_mnt_opts *opts = mnt_opts; struct inode_security_struct *root_isec; @@ -881,8 +869,8 @@ static int selinux_set_mnt_opts(struct super_block *sb, static int selinux_cmp_sb_context(const struct super_block *oldsb, const struct super_block *newsb) { - struct superblock_security_struct *old = oldsb->s_security; - struct superblock_security_struct *new = newsb->s_security; + struct superblock_security_struct *old = selinux_superblock(oldsb); + struct superblock_security_struct *new = selinux_superblock(newsb); char oldflags = old->flags & SE_MNTMASK; char newflags = new->flags & SE_MNTMASK; @@ -914,8 +902,9 @@ static int selinux_sb_clone_mnt_opts(const struct super_block *oldsb, unsigned long *set_kern_flags) { int rc = 0; - const struct superblock_security_struct *oldsbsec = oldsb->s_security; - struct superblock_security_struct *newsbsec = newsb->s_security; + const struct superblock_security_struct *oldsbsec = + selinux_superblock(oldsb); + struct superblock_security_struct *newsbsec = selinux_superblock(newsb); int set_fscontext = (oldsbsec->flags & FSCONTEXT_MNT); int set_context = (oldsbsec->flags & CONTEXT_MNT); @@ -1085,7 +1074,7 @@ static int show_sid(struct seq_file *m, u32 sid) static int selinux_sb_show_options(struct seq_file *m, struct super_block *sb) { - struct superblock_security_struct *sbsec = sb->s_security; + struct superblock_security_struct *sbsec = selinux_superblock(sb); int rc; if (!(sbsec->flags & SE_SBINITIALIZED)) @@ -1377,7 +1366,7 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent if (isec->sclass == SECCLASS_FILE) isec->sclass = inode_mode_to_security_class(inode->i_mode); - sbsec = inode->i_sb->s_security; + sbsec = selinux_superblock(inode->i_sb); if (!(sbsec->flags & SE_SBINITIALIZED)) { /* Defer initialization until selinux_complete_init, after the initial policy is loaded and the security @@ -1767,7 +1756,8 @@ selinux_determine_inode_label(const struct task_security_struct *tsec, const struct qstr *name, u16 tclass, u32 *_new_isid) { - const struct superblock_security_struct *sbsec = dir->i_sb->s_security; + const struct superblock_security_struct *sbsec = + selinux_superblock(dir->i_sb); if ((sbsec->flags & SE_SBINITIALIZED) && (sbsec->behavior == SECURITY_FS_USE_MNTPOINT)) { @@ -1798,7 +1788,7 @@ static int may_create(struct inode *dir, int rc; dsec = inode_security(dir); - sbsec = dir->i_sb->s_security; + sbsec = selinux_superblock(dir->i_sb); sid = tsec->sid; @@ -1947,7 +1937,7 @@ static int superblock_has_perm(const struct cred *cred, struct superblock_security_struct *sbsec; u32 sid = cred_sid(cred); - sbsec = sb->s_security; + sbsec = selinux_superblock(sb); return avc_has_perm(&selinux_state, sid, sbsec->sid, SECCLASS_FILESYSTEM, perms, ad); } @@ -2578,11 +2568,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 opt_len(const char *s) { bool open_quote = false; @@ -2653,7 +2638,7 @@ static int selinux_sb_eat_lsm_opts(char *options, void **mnt_opts) static int selinux_sb_remount(struct super_block *sb, void *mnt_opts) { struct selinux_mnt_opts *opts = mnt_opts; - struct superblock_security_struct *sbsec = sb->s_security; + struct superblock_security_struct *sbsec = selinux_superblock(sb); u32 sid; int rc; @@ -2877,7 +2862,7 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir, int rc; char *context; - sbsec = dir->i_sb->s_security; + sbsec = selinux_superblock(dir->i_sb); newsid = tsec->create_sid; @@ -3115,7 +3100,7 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name, return dentry_has_perm(current_cred(), dentry, FILE__SETATTR); } - sbsec = inode->i_sb->s_security; + sbsec = selinux_superblock(inode->i_sb); if (!(sbsec->flags & SBLABEL_MNT)) return -EOPNOTSUPP; @@ -3296,13 +3281,14 @@ static int selinux_inode_setsecurity(struct inode *inode, const char *name, const void *value, size_t size, int flags) { struct inode_security_struct *isec = inode_security_novalidate(inode); - struct superblock_security_struct *sbsec = inode->i_sb->s_security; + struct superblock_security_struct *sbsec; u32 newsid; int rc; if (strcmp(name, XATTR_SELINUX_SUFFIX)) return -EOPNOTSUPP; + sbsec = selinux_superblock(inode->i_sb); if (!(sbsec->flags & SBLABEL_MNT)) return -EOPNOTSUPP; @@ -6647,6 +6633,7 @@ struct lsm_blob_sizes selinux_blob_sizes __lsm_ro_after_init = { .lbs_inode = sizeof(struct inode_security_struct), .lbs_ipc = sizeof(struct ipc_security_struct), .lbs_msg_msg = sizeof(struct msg_security_struct), + .lbs_superblock = sizeof(struct superblock_security_struct), }; static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = { @@ -6675,7 +6662,6 @@ static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = { LSM_HOOK_INIT(fs_context_parse_param, selinux_fs_context_parse_param), LSM_HOOK_INIT(sb_alloc_security, selinux_sb_alloc_security), - LSM_HOOK_INIT(sb_free_security, selinux_sb_free_security), LSM_HOOK_INIT(sb_eat_lsm_opts, selinux_sb_eat_lsm_opts), LSM_HOOK_INIT(sb_free_mnt_opts, selinux_free_mnt_opts), LSM_HOOK_INIT(sb_remount, selinux_sb_remount), diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h index 231262d8eac9..d08d7e5d2f93 100644 --- a/security/selinux/include/objsec.h +++ b/security/selinux/include/objsec.h @@ -188,4 +188,10 @@ static inline struct ipc_security_struct *selinux_ipc( return ipc->security + selinux_blob_sizes.lbs_ipc; } +static inline struct superblock_security_struct *selinux_superblock( + const struct super_block *superblock) +{ + return superblock->s_security + selinux_blob_sizes.lbs_superblock; +} + #endif /* _SELINUX_OBJSEC_H_ */ diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index ec62918521b1..e3f5d6aece66 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c @@ -50,6 +50,7 @@ #include #include #include +#include #include #include "flask.h" @@ -2751,7 +2752,7 @@ int security_fs_use(struct selinux_state *state, struct super_block *sb) struct sidtab *sidtab; int rc = 0; struct ocontext *c; - struct superblock_security_struct *sbsec = sb->s_security; + struct superblock_security_struct *sbsec = selinux_superblock(sb); const char *fstype = sb->s_type->name; read_lock(&state->ss->policy_rwlock); diff --git a/security/smack/smack.h b/security/smack/smack.h index cf52af77d15e..caecbcba9942 100644 --- a/security/smack/smack.h +++ b/security/smack/smack.h @@ -375,6 +375,12 @@ static inline struct smack_known **smack_ipc(const struct kern_ipc_perm *ipc) return ipc->security + smack_blob_sizes.lbs_ipc; } +static inline struct superblock_smack *smack_superblock( + const struct super_block *superblock) +{ + return superblock->s_security + smack_blob_sizes.lbs_superblock; +} + /* * Is the directory transmuting? */ diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index 5c1613519d5a..807eff2ccce9 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -540,12 +540,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; @@ -554,22 +549,10 @@ 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) -{ - kfree(sb->s_security); - sb->s_security = NULL; -} - struct smack_mnt_opts { const char *fsdefault, *fsfloor, *fshat, *fsroot, *fstransmute; }; @@ -781,7 +764,7 @@ static int smack_set_mnt_opts(struct super_block *sb, { struct dentry *root = sb->s_root; struct inode *inode = d_backing_inode(root); - struct superblock_smack *sp = sb->s_security; + struct superblock_smack *sp = smack_superblock(sb); struct inode_smack *isp; struct smack_known *skp; struct smack_mnt_opts *opts = mnt_opts; @@ -880,7 +863,7 @@ static int smack_set_mnt_opts(struct super_block *sb, */ static int smack_sb_statfs(struct dentry *dentry) { - struct superblock_smack *sbp = dentry->d_sb->s_security; + struct superblock_smack *sbp = smack_superblock(dentry->d_sb); int rc; struct smk_audit_info ad; @@ -917,7 +900,7 @@ static int smack_bprm_set_creds(struct linux_binprm *bprm) if (isp->smk_task == NULL || isp->smk_task == bsp->smk_task) return 0; - sbsp = inode->i_sb->s_security; + sbsp = smack_superblock(inode->i_sb); if ((sbsp->smk_flags & SMK_SB_UNTRUSTED) && isp->smk_task != sbsp->smk_root) return 0; @@ -1168,7 +1151,7 @@ static int smack_inode_rename(struct inode *old_inode, */ static int smack_inode_permission(struct inode *inode, int mask) { - struct superblock_smack *sbsp = inode->i_sb->s_security; + struct superblock_smack *sbsp = smack_superblock(inode->i_sb); struct smk_audit_info ad; int no_block = mask & MAY_NOT_BLOCK; int rc; @@ -1410,7 +1393,7 @@ static int smack_inode_removexattr(struct dentry *dentry, const char *name) */ if (strcmp(name, XATTR_NAME_SMACK) == 0) { struct super_block *sbp = dentry->d_sb; - struct superblock_smack *sbsp = sbp->s_security; + struct superblock_smack *sbsp = smack_superblock(sbp); isp->smk_inode = sbsp->smk_default; } else if (strcmp(name, XATTR_NAME_SMACKEXEC) == 0) @@ -1680,7 +1663,7 @@ static int smack_mmap_file(struct file *file, isp = smack_inode(file_inode(file)); if (isp->smk_mmap == NULL) return 0; - sbsp = file_inode(file)->i_sb->s_security; + sbsp = smack_superblock(file_inode(file)->i_sb); if (sbsp->smk_flags & SMK_SB_UNTRUSTED && isp->smk_mmap != sbsp->smk_root) return -EACCES; @@ -3288,7 +3271,7 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode) goto unlockandout; sbp = inode->i_sb; - sbsp = sbp->s_security; + sbsp = smack_superblock(sbp); /* * We're going to use the superblock default label * if there's no label on the file. @@ -4575,6 +4558,7 @@ struct lsm_blob_sizes smack_blob_sizes __lsm_ro_after_init = { .lbs_inode = sizeof(struct inode_smack), .lbs_ipc = sizeof(struct smack_known *), .lbs_msg_msg = sizeof(struct smack_known *), + .lbs_superblock = sizeof(struct superblock_smack), }; static struct security_hook_list smack_hooks[] __lsm_ro_after_init = { @@ -4586,7 +4570,6 @@ static struct security_hook_list smack_hooks[] __lsm_ro_after_init = { LSM_HOOK_INIT(fs_context_parse_param, smack_fs_context_parse_param), LSM_HOOK_INIT(sb_alloc_security, smack_sb_alloc_security), - LSM_HOOK_INIT(sb_free_security, smack_sb_free_security), LSM_HOOK_INIT(sb_free_mnt_opts, smack_free_mnt_opts), LSM_HOOK_INIT(sb_eat_lsm_opts, smack_sb_eat_lsm_opts), LSM_HOOK_INIT(sb_statfs, smack_sb_statfs), From patchwork Thu Aug 29 23:29:09 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 11122693 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id F31421399 for ; Thu, 29 Aug 2019 23:31:45 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id A87462173E for ; Thu, 29 Aug 2019 23:31:45 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="I0i9X/v1" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1725917AbfH2Xbp (ORCPT ); Thu, 29 Aug 2019 19:31:45 -0400 Received: from sonic307-4.consmr.mail.ne1.yahoo.com ([66.163.190.123]:41661 "EHLO sonic307-4.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725999AbfH2Xbp (ORCPT ); Thu, 29 Aug 2019 19:31:45 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1567121499; bh=oN+hBCYPqJSNg2iAL0HOUoaPMu0+iTYeZfWhVKinr0U=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=I0i9X/v1nlMUHQM3hjIQ8Frbm00jzXhpmR+mDmNZ+/XA1qBlrzsoqPiD7LjVz1zfdxwpmxO77XE8bqyP+jL1BVQ6SBQuI5sbvphgccwSglg/7MkSuneaGU3rwL7d0OmbyqTbgeRMavAh+J8EYhvj5pupr4BrLcZ3Xf71hEBbkCx4sMUAj4pt0Q7CbZXbJgI3V5q0eY+bUz6okBh06wPSGI69mekOWqC2NVuByWgwyPHeV6qBm+dpfNHklo0Cv5/WA/IElQIWHVywIVMfgN+aVd7X7IvD96PMP2isLSC0NGt1JggbVo5ZCc622azjwXK2wTyAlq1tyIiu7lHa5KE/5Q== X-YMail-OSG: ezJ81BYVM1nFmJIbMdBpMRKaBhLYLPKIkDoohs8Pv7D.oZIU3Fa.gQIeVODcdVU 6yxEXzG8x1ivbMwikMfgQyIasObJkg0.5j_iSQ6Z7UToRxwoHjTjW1qtomMTrq4NUwQ0xoEp1p63 digzSphvjmP53R7tT.3oDJMHReEC_A0nv4giK5VFsMrQxDkc3ygV5w51RkTLx2JZkoyyQqbVFTBJ 4yO_c9mW.KVsuZRLuj5c1O6W6AhHoX4Ll12oi_59RqipnTfhMlYACCnMJcBOn8PpA0jXXEBJjXtw 0weUne70lH.jkFOl8SFRZNJqlVbli7iNOX8QqwQqz.3Tki5KjnT0j71s0jlG_2Sdzg263xujri.W Sao_ZDXDTCKFN9OPsHMUYGT5EFpRkmurVW4RFiZW6ojwfbZTuTY3v4S5ccjV6ifxNZvM2m8dhXJi PWntDhTmiU0IkchECHX8ihcFUnvemg3XIRpXZjSwsUfKgSAVvmYjKqgR02uPfW3iuT_3_SokqfPH q.CxnFEGCS.c622h20QhXiDYB6kxILW5y8HQ8vWtAcJaiBDLVvYCtEkcXY53MsHXBFxdl1DhNn0r TIz2Y40HigShuRfkd8UQJaDin3xVwoWPaTwtCla3BRp0UtsGT9BJw.5szkMRVhReVa3ZRKWxp64K fiHiP83fgDaVdO1hw3GtrIOoKdk76nBiNR9ZitT1.k0uqWKpHCmMxztiaSgtaQtSsQN4AoLRrEbz I2Yp6AcDN.EgKE3.7zfgCBrP4XJ2sWi8ylFZEd.lsbierl3GjACBOOv.UvkMMzK3LJuYovrpCweG 3VVujjoS7EGvBC64Kj3JJNPYUqHWHAzXyIU_.VFpFjFHIlatoDZoSRu3gjaOmtLqBQKX1NzEZCRy XPgn6HyqhhE_brDD6EBtMeG6xwicDpp4LD5U8YaBUjTn3nhqbjuHgJ8ZzO.eZVUXFaQ1GhZu.35u ooH0pW4ZcCTKSMd5UkYb5JYtkehX1j.4LFsHF3CSGJd1dCQ9dwwe2ii8QCWp8w2m8Jlq9UQDPwXF mkVEgmTPeRlcVRNkATrWttz.Lv3SbJF4nFjQoR6WgP7oGmhINZjMBt5wHIVPA.wqqc3oDG5EotWc oFnntRb2.wdtMYs..rMhM2kuBjP090xFj0_8_BFtLA39FKtaXHDp6AC9Wildef_eGovlzZpl__cO HGB1KdZnqL7uFCZ8Q2vmt_WJ0U8pZY98cFqbjVxsXi6JIPrB_kdA2G8l7ps4l99.Lho3y3FVjNEz x_LsdONnhYqmoTNEtpGlxitB4Ju9VqUmAeKK1NiCVmD6G11MUHEn70TAejVoGimgC8mZss8mPeDo QmsoGLSs- Received: from sonic.gate.mail.ne1.yahoo.com by sonic307.consmr.mail.ne1.yahoo.com with HTTP; Thu, 29 Aug 2019 23:31:39 +0000 Received: by smtp403.mail.ne1.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID 348e1bb830015a550a7ef552e960420a; Thu, 29 Aug 2019 23:29:39 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, jmorris@namei.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org Cc: casey@schaufler-ca.com, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, paul@paul-moore.com, sds@tycho.nsa.gov Subject: [PATCH v8 02/28] LSM: Infrastructure management of the sock security Date: Thu, 29 Aug 2019 16:29:09 -0700 Message-Id: <20190829232935.7099-3-casey@schaufler-ca.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190829232935.7099-1-casey@schaufler-ca.com> References: <20190829232935.7099-1-casey@schaufler-ca.com> MIME-Version: 1.0 Sender: selinux-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: selinux@vger.kernel.org Move management of the sock->sk_security blob out of the individual security modules and into the security infrastructure. Instead of allocating the blobs from within the modules the modules tell the infrastructure how much space is required, and the space is allocated there. Reviewed-by: Kees Cook Reviewed-by: John Johansen Signed-off-by: Casey Schaufler Reviewed-by: Stephen Smalley --- include/linux/lsm_hooks.h | 1 + security/apparmor/include/net.h | 6 ++- security/apparmor/lsm.c | 38 ++++----------- security/security.c | 36 +++++++++++++- security/selinux/hooks.c | 78 +++++++++++++++---------------- security/selinux/include/objsec.h | 5 ++ security/selinux/netlabel.c | 23 ++++----- security/smack/smack.h | 5 ++ security/smack/smack_lsm.c | 64 ++++++++++++------------- security/smack/smack_netfilter.c | 8 ++-- 10 files changed, 144 insertions(+), 120 deletions(-) diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h index f9222a04968d..b353482ea348 100644 --- a/include/linux/lsm_hooks.h +++ b/include/linux/lsm_hooks.h @@ -2047,6 +2047,7 @@ struct lsm_blob_sizes { int lbs_cred; int lbs_file; int lbs_inode; + int lbs_sock; int lbs_superblock; int lbs_ipc; int lbs_msg_msg; diff --git a/security/apparmor/include/net.h b/security/apparmor/include/net.h index 7334ac966d01..adac04e3b3cc 100644 --- a/security/apparmor/include/net.h +++ b/security/apparmor/include/net.h @@ -55,7 +55,11 @@ struct aa_sk_ctx { struct aa_label *peer; }; -#define SK_CTX(X) ((X)->sk_security) +static inline struct aa_sk_ctx *aa_sock(const struct sock *sk) +{ + return sk->sk_security + apparmor_blob_sizes.lbs_sock; +} + #define SOCK_ctx(X) SOCK_INODE(X)->i_security #define DEFINE_AUDIT_NET(NAME, OP, SK, F, T, P) \ struct lsm_network_audit NAME ## _net = { .sk = (SK), \ diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c index 49d664ddff44..2716e7731279 100644 --- a/security/apparmor/lsm.c +++ b/security/apparmor/lsm.c @@ -757,33 +757,15 @@ static int apparmor_task_kill(struct task_struct *target, struct kernel_siginfo return error; } -/** - * apparmor_sk_alloc_security - allocate and attach the sk_security field - */ -static int apparmor_sk_alloc_security(struct sock *sk, int family, gfp_t flags) -{ - struct aa_sk_ctx *ctx; - - ctx = kzalloc(sizeof(*ctx), flags); - if (!ctx) - return -ENOMEM; - - SK_CTX(sk) = ctx; - - return 0; -} - /** * apparmor_sk_free_security - free the sk_security field */ static void apparmor_sk_free_security(struct sock *sk) { - struct aa_sk_ctx *ctx = SK_CTX(sk); + struct aa_sk_ctx *ctx = aa_sock(sk); - SK_CTX(sk) = NULL; aa_put_label(ctx->label); aa_put_label(ctx->peer); - kfree(ctx); } /** @@ -792,8 +774,8 @@ static void apparmor_sk_free_security(struct sock *sk) static void apparmor_sk_clone_security(const struct sock *sk, struct sock *newsk) { - struct aa_sk_ctx *ctx = SK_CTX(sk); - struct aa_sk_ctx *new = SK_CTX(newsk); + struct aa_sk_ctx *ctx = aa_sock(sk); + struct aa_sk_ctx *new = aa_sock(newsk); new->label = aa_get_label(ctx->label); new->peer = aa_get_label(ctx->peer); @@ -844,7 +826,7 @@ static int apparmor_socket_post_create(struct socket *sock, int family, label = aa_get_current_label(); if (sock->sk) { - struct aa_sk_ctx *ctx = SK_CTX(sock->sk); + struct aa_sk_ctx *ctx = aa_sock(sock->sk); aa_put_label(ctx->label); ctx->label = aa_get_label(label); @@ -1029,7 +1011,7 @@ static int apparmor_socket_shutdown(struct socket *sock, int how) */ static int apparmor_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) { - struct aa_sk_ctx *ctx = SK_CTX(sk); + struct aa_sk_ctx *ctx = aa_sock(sk); if (!skb->secmark) return 0; @@ -1042,7 +1024,7 @@ static int apparmor_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) static struct aa_label *sk_peer_label(struct sock *sk) { - struct aa_sk_ctx *ctx = SK_CTX(sk); + struct aa_sk_ctx *ctx = aa_sock(sk); if (ctx->peer) return ctx->peer; @@ -1126,7 +1108,7 @@ static int apparmor_socket_getpeersec_dgram(struct socket *sock, */ static void apparmor_sock_graft(struct sock *sk, struct socket *parent) { - struct aa_sk_ctx *ctx = SK_CTX(sk); + struct aa_sk_ctx *ctx = aa_sock(sk); if (!ctx->label) ctx->label = aa_get_current_label(); @@ -1136,7 +1118,7 @@ static void apparmor_sock_graft(struct sock *sk, struct socket *parent) static int apparmor_inet_conn_request(struct sock *sk, struct sk_buff *skb, struct request_sock *req) { - struct aa_sk_ctx *ctx = SK_CTX(sk); + struct aa_sk_ctx *ctx = aa_sock(sk); if (!skb->secmark) return 0; @@ -1153,6 +1135,7 @@ struct lsm_blob_sizes apparmor_blob_sizes __lsm_ro_after_init = { .lbs_cred = sizeof(struct aa_task_ctx *), .lbs_file = sizeof(struct aa_file_ctx), .lbs_task = sizeof(struct aa_task_ctx), + .lbs_sock = sizeof(struct aa_sk_ctx), }; static struct security_hook_list apparmor_hooks[] __lsm_ro_after_init = { @@ -1189,7 +1172,6 @@ static struct security_hook_list apparmor_hooks[] __lsm_ro_after_init = { LSM_HOOK_INIT(getprocattr, apparmor_getprocattr), LSM_HOOK_INIT(setprocattr, apparmor_setprocattr), - LSM_HOOK_INIT(sk_alloc_security, apparmor_sk_alloc_security), LSM_HOOK_INIT(sk_free_security, apparmor_sk_free_security), LSM_HOOK_INIT(sk_clone_security, apparmor_sk_clone_security), @@ -1581,7 +1563,7 @@ static unsigned int apparmor_ip_postroute(void *priv, if (sk == NULL) return NF_ACCEPT; - ctx = SK_CTX(sk); + ctx = aa_sock(sk); if (!apparmor_secmark_check(ctx->label, OP_SENDMSG, AA_MAY_SEND, skb->secmark, sk)) return NF_ACCEPT; diff --git a/security/security.c b/security/security.c index 86198e303203..2c0834db7976 100644 --- a/security/security.c +++ b/security/security.c @@ -32,6 +32,7 @@ #include #include #include +#include #define MAX_LSM_EVM_XATTR 2 @@ -172,6 +173,7 @@ static void __init lsm_set_blob_sizes(struct lsm_blob_sizes *needed) lsm_set_blob_size(&needed->lbs_inode, &blob_sizes.lbs_inode); lsm_set_blob_size(&needed->lbs_ipc, &blob_sizes.lbs_ipc); lsm_set_blob_size(&needed->lbs_msg_msg, &blob_sizes.lbs_msg_msg); + lsm_set_blob_size(&needed->lbs_sock, &blob_sizes.lbs_sock); lsm_set_blob_size(&needed->lbs_superblock, &blob_sizes.lbs_superblock); lsm_set_blob_size(&needed->lbs_task, &blob_sizes.lbs_task); } @@ -306,6 +308,7 @@ static void __init ordered_lsm_init(void) init_debug("inode blob size = %d\n", blob_sizes.lbs_inode); init_debug("ipc blob size = %d\n", blob_sizes.lbs_ipc); init_debug("msg_msg blob size = %d\n", blob_sizes.lbs_msg_msg); + init_debug("sock blob size = %d\n", blob_sizes.lbs_sock); init_debug("superblock blob size = %d\n", blob_sizes.lbs_superblock); init_debug("task blob size = %d\n", blob_sizes.lbs_task); @@ -605,6 +608,28 @@ static void __init lsm_early_task(struct task_struct *task) panic("%s: Early task alloc failed.\n", __func__); } +/** + * lsm_sock_alloc - allocate a composite sock blob + * @sock: the sock that needs a blob + * @priority: allocation mode + * + * Allocate the sock blob for all the modules + * + * Returns 0, or -ENOMEM if memory can't be allocated. + */ +static int lsm_sock_alloc(struct sock *sock, gfp_t priority) +{ + if (blob_sizes.lbs_sock == 0) { + sock->sk_security = NULL; + return 0; + } + + sock->sk_security = kzalloc(blob_sizes.lbs_sock, priority); + if (sock->sk_security == NULL) + return -ENOMEM; + return 0; +} + /** * lsm_superblock_alloc - allocate a composite superblock blob * @sb: the superblock that needs a blob @@ -2048,12 +2073,21 @@ EXPORT_SYMBOL(security_socket_getpeersec_dgram); int security_sk_alloc(struct sock *sk, int family, gfp_t priority) { - return call_int_hook(sk_alloc_security, 0, sk, family, priority); + int rc = lsm_sock_alloc(sk, priority); + + if (unlikely(rc)) + return rc; + rc = call_int_hook(sk_alloc_security, 0, sk, family, priority); + if (unlikely(rc)) + security_sk_free(sk); + return rc; } void security_sk_free(struct sock *sk) { call_void_hook(sk_free_security, sk); + kfree(sk->sk_security); + sk->sk_security = NULL; } void security_sk_clone(const struct sock *sk, struct sock *newsk) diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 7478d8eda00a..5d74ed35b728 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -4319,7 +4319,7 @@ static int socket_sockcreate_sid(const struct task_security_struct *tsec, static int sock_has_perm(struct sock *sk, u32 perms) { - struct sk_security_struct *sksec = sk->sk_security; + struct sk_security_struct *sksec = selinux_sock(sk); struct common_audit_data ad; struct lsm_network_audit net = {0,}; @@ -4376,7 +4376,7 @@ static int selinux_socket_post_create(struct socket *sock, int family, isec->initialized = LABEL_INITIALIZED; if (sock->sk) { - sksec = sock->sk->sk_security; + sksec = selinux_sock(sock->sk); sksec->sclass = sclass; sksec->sid = sid; /* Allows detection of the first association on this socket */ @@ -4392,8 +4392,8 @@ static int selinux_socket_post_create(struct socket *sock, int family, static int selinux_socket_socketpair(struct socket *socka, struct socket *sockb) { - struct sk_security_struct *sksec_a = socka->sk->sk_security; - struct sk_security_struct *sksec_b = sockb->sk->sk_security; + struct sk_security_struct *sksec_a = selinux_sock(socka->sk); + struct sk_security_struct *sksec_b = selinux_sock(sockb->sk); sksec_a->peer_sid = sksec_b->sid; sksec_b->peer_sid = sksec_a->sid; @@ -4408,7 +4408,7 @@ static int selinux_socket_socketpair(struct socket *socka, static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, int addrlen) { struct sock *sk = sock->sk; - struct sk_security_struct *sksec = sk->sk_security; + struct sk_security_struct *sksec = selinux_sock(sk); u16 family; int err; @@ -4540,7 +4540,7 @@ static int selinux_socket_connect_helper(struct socket *sock, struct sockaddr *address, int addrlen) { struct sock *sk = sock->sk; - struct sk_security_struct *sksec = sk->sk_security; + struct sk_security_struct *sksec = selinux_sock(sk); int err; err = sock_has_perm(sk, SOCKET__CONNECT); @@ -4711,9 +4711,9 @@ static int selinux_socket_unix_stream_connect(struct sock *sock, struct sock *other, struct sock *newsk) { - struct sk_security_struct *sksec_sock = sock->sk_security; - struct sk_security_struct *sksec_other = other->sk_security; - struct sk_security_struct *sksec_new = newsk->sk_security; + struct sk_security_struct *sksec_sock = selinux_sock(sock); + struct sk_security_struct *sksec_other = selinux_sock(other); + struct sk_security_struct *sksec_new = selinux_sock(newsk); struct common_audit_data ad; struct lsm_network_audit net = {0,}; int err; @@ -4745,8 +4745,8 @@ static int selinux_socket_unix_stream_connect(struct sock *sock, static int selinux_socket_unix_may_send(struct socket *sock, struct socket *other) { - struct sk_security_struct *ssec = sock->sk->sk_security; - struct sk_security_struct *osec = other->sk->sk_security; + struct sk_security_struct *ssec = selinux_sock(sock->sk); + struct sk_security_struct *osec = selinux_sock(other->sk); struct common_audit_data ad; struct lsm_network_audit net = {0,}; @@ -4788,7 +4788,7 @@ static int selinux_sock_rcv_skb_compat(struct sock *sk, struct sk_buff *skb, u16 family) { int err = 0; - struct sk_security_struct *sksec = sk->sk_security; + struct sk_security_struct *sksec = selinux_sock(sk); u32 sk_sid = sksec->sid; struct common_audit_data ad; struct lsm_network_audit net = {0,}; @@ -4821,7 +4821,7 @@ static int selinux_sock_rcv_skb_compat(struct sock *sk, struct sk_buff *skb, static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) { int err; - struct sk_security_struct *sksec = sk->sk_security; + struct sk_security_struct *sksec = selinux_sock(sk); u16 family = sk->sk_family; u32 sk_sid = sksec->sid; struct common_audit_data ad; @@ -4889,13 +4889,15 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) return err; } -static int selinux_socket_getpeersec_stream(struct socket *sock, char __user *optval, - int __user *optlen, unsigned len) +static int selinux_socket_getpeersec_stream(struct socket *sock, + char __user *optval, + int __user *optlen, + unsigned int len) { int err = 0; char *scontext; u32 scontext_len; - struct sk_security_struct *sksec = sock->sk->sk_security; + struct sk_security_struct *sksec = selinux_sock(sock->sk); u32 peer_sid = SECSID_NULL; if (sksec->sclass == SECCLASS_UNIX_STREAM_SOCKET || @@ -4955,34 +4957,27 @@ static int selinux_socket_getpeersec_dgram(struct socket *sock, struct sk_buff * static int selinux_sk_alloc_security(struct sock *sk, int family, gfp_t priority) { - struct sk_security_struct *sksec; - - sksec = kzalloc(sizeof(*sksec), priority); - if (!sksec) - return -ENOMEM; + struct sk_security_struct *sksec = selinux_sock(sk); sksec->peer_sid = SECINITSID_UNLABELED; sksec->sid = SECINITSID_UNLABELED; sksec->sclass = SECCLASS_SOCKET; selinux_netlbl_sk_security_reset(sksec); - sk->sk_security = sksec; return 0; } static void selinux_sk_free_security(struct sock *sk) { - struct sk_security_struct *sksec = sk->sk_security; + struct sk_security_struct *sksec = selinux_sock(sk); - sk->sk_security = NULL; selinux_netlbl_sk_security_free(sksec); - kfree(sksec); } static void selinux_sk_clone_security(const struct sock *sk, struct sock *newsk) { - struct sk_security_struct *sksec = sk->sk_security; - struct sk_security_struct *newsksec = newsk->sk_security; + struct sk_security_struct *sksec = selinux_sock(sk); + struct sk_security_struct *newsksec = selinux_sock(newsk); newsksec->sid = sksec->sid; newsksec->peer_sid = sksec->peer_sid; @@ -4996,7 +4991,7 @@ static void selinux_sk_getsecid(struct sock *sk, u32 *secid) if (!sk) *secid = SECINITSID_ANY_SOCKET; else { - struct sk_security_struct *sksec = sk->sk_security; + struct sk_security_struct *sksec = selinux_sock(sk); *secid = sksec->sid; } @@ -5006,7 +5001,7 @@ static void selinux_sock_graft(struct sock *sk, struct socket *parent) { struct inode_security_struct *isec = inode_security_novalidate(SOCK_INODE(parent)); - struct sk_security_struct *sksec = sk->sk_security; + struct sk_security_struct *sksec = selinux_sock(sk); if (sk->sk_family == PF_INET || sk->sk_family == PF_INET6 || sk->sk_family == PF_UNIX) @@ -5021,7 +5016,7 @@ static void selinux_sock_graft(struct sock *sk, struct socket *parent) static int selinux_sctp_assoc_request(struct sctp_endpoint *ep, struct sk_buff *skb) { - struct sk_security_struct *sksec = ep->base.sk->sk_security; + struct sk_security_struct *sksec = selinux_sock(ep->base.sk); struct common_audit_data ad; struct lsm_network_audit net = {0,}; u8 peerlbl_active; @@ -5172,8 +5167,8 @@ static int selinux_sctp_bind_connect(struct sock *sk, int optname, static void selinux_sctp_sk_clone(struct sctp_endpoint *ep, struct sock *sk, struct sock *newsk) { - struct sk_security_struct *sksec = sk->sk_security; - struct sk_security_struct *newsksec = newsk->sk_security; + struct sk_security_struct *sksec = selinux_sock(sk); + struct sk_security_struct *newsksec = selinux_sock(newsk); /* If policy does not support SECCLASS_SCTP_SOCKET then call * the non-sctp clone version. @@ -5190,7 +5185,7 @@ static void selinux_sctp_sk_clone(struct sctp_endpoint *ep, struct sock *sk, static int selinux_inet_conn_request(struct sock *sk, struct sk_buff *skb, struct request_sock *req) { - struct sk_security_struct *sksec = sk->sk_security; + struct sk_security_struct *sksec = selinux_sock(sk); int err; u16 family = req->rsk_ops->family; u32 connsid; @@ -5211,7 +5206,7 @@ static int selinux_inet_conn_request(struct sock *sk, struct sk_buff *skb, static void selinux_inet_csk_clone(struct sock *newsk, const struct request_sock *req) { - struct sk_security_struct *newsksec = newsk->sk_security; + struct sk_security_struct *newsksec = selinux_sock(newsk); newsksec->sid = req->secid; newsksec->peer_sid = req->peer_secid; @@ -5228,7 +5223,7 @@ static void selinux_inet_csk_clone(struct sock *newsk, static void selinux_inet_conn_established(struct sock *sk, struct sk_buff *skb) { u16 family = sk->sk_family; - struct sk_security_struct *sksec = sk->sk_security; + struct sk_security_struct *sksec = selinux_sock(sk); /* handle mapped IPv4 packets arriving via IPv6 sockets */ if (family == PF_INET6 && skb->protocol == htons(ETH_P_IP)) @@ -5312,7 +5307,7 @@ static int selinux_tun_dev_attach_queue(void *security) static int selinux_tun_dev_attach(struct sock *sk, void *security) { struct tun_security_struct *tunsec = security; - struct sk_security_struct *sksec = sk->sk_security; + struct sk_security_struct *sksec = selinux_sock(sk); /* we don't currently perform any NetLabel based labeling here and it * isn't clear that we would want to do so anyway; while we could apply @@ -5353,7 +5348,7 @@ static int selinux_nlmsg_perm(struct sock *sk, struct sk_buff *skb) int err = 0; u32 perm; struct nlmsghdr *nlh; - struct sk_security_struct *sksec = sk->sk_security; + struct sk_security_struct *sksec = selinux_sock(sk); if (skb->len < NLMSG_HDRLEN) { err = -EINVAL; @@ -5494,7 +5489,7 @@ static unsigned int selinux_ip_output(struct sk_buff *skb, return NF_ACCEPT; /* standard practice, label using the parent socket */ - sksec = sk->sk_security; + sksec = selinux_sock(sk); sid = sksec->sid; } else sid = SECINITSID_KERNEL; @@ -5533,7 +5528,7 @@ static unsigned int selinux_ip_postroute_compat(struct sk_buff *skb, if (sk == NULL) return NF_ACCEPT; - sksec = sk->sk_security; + sksec = selinux_sock(sk); ad.type = LSM_AUDIT_DATA_NET; ad.u.net = &net; @@ -5625,7 +5620,7 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, u32 skb_sid; struct sk_security_struct *sksec; - sksec = sk->sk_security; + sksec = selinux_sock(sk); if (selinux_skb_peerlbl_sid(skb, family, &skb_sid)) return NF_DROP; /* At this point, if the returned skb peerlbl is SECSID_NULL @@ -5654,7 +5649,7 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, } else { /* Locally generated packet, fetch the security label from the * associated socket. */ - struct sk_security_struct *sksec = sk->sk_security; + struct sk_security_struct *sksec = selinux_sock(sk); peer_sid = sksec->sid; secmark_perm = PACKET__SEND; } @@ -6633,6 +6628,7 @@ struct lsm_blob_sizes selinux_blob_sizes __lsm_ro_after_init = { .lbs_inode = sizeof(struct inode_security_struct), .lbs_ipc = sizeof(struct ipc_security_struct), .lbs_msg_msg = sizeof(struct msg_security_struct), + .lbs_sock = sizeof(struct sk_security_struct), .lbs_superblock = sizeof(struct superblock_security_struct), }; diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h index d08d7e5d2f93..29f02b8f8f31 100644 --- a/security/selinux/include/objsec.h +++ b/security/selinux/include/objsec.h @@ -194,4 +194,9 @@ static inline struct superblock_security_struct *selinux_superblock( return superblock->s_security + selinux_blob_sizes.lbs_superblock; } +static inline struct sk_security_struct *selinux_sock(const struct sock *sock) +{ + return sock->sk_security + selinux_blob_sizes.lbs_sock; +} + #endif /* _SELINUX_OBJSEC_H_ */ diff --git a/security/selinux/netlabel.c b/security/selinux/netlabel.c index 186e727b737b..c40914a157b7 100644 --- a/security/selinux/netlabel.c +++ b/security/selinux/netlabel.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -81,7 +82,7 @@ static int selinux_netlbl_sidlookup_cached(struct sk_buff *skb, static struct netlbl_lsm_secattr *selinux_netlbl_sock_genattr(struct sock *sk) { int rc; - struct sk_security_struct *sksec = sk->sk_security; + struct sk_security_struct *sksec = selinux_sock(sk); struct netlbl_lsm_secattr *secattr; if (sksec->nlbl_secattr != NULL) @@ -114,7 +115,7 @@ static struct netlbl_lsm_secattr *selinux_netlbl_sock_getattr( const struct sock *sk, u32 sid) { - struct sk_security_struct *sksec = sk->sk_security; + struct sk_security_struct *sksec = selinux_sock(sk); struct netlbl_lsm_secattr *secattr = sksec->nlbl_secattr; if (secattr == NULL) @@ -249,7 +250,7 @@ int selinux_netlbl_skbuff_setsid(struct sk_buff *skb, * being labeled by it's parent socket, if it is just exit */ sk = skb_to_full_sk(skb); if (sk != NULL) { - struct sk_security_struct *sksec = sk->sk_security; + struct sk_security_struct *sksec = selinux_sock(sk); if (sksec->nlbl_state != NLBL_REQSKB) return 0; @@ -287,7 +288,7 @@ int selinux_netlbl_sctp_assoc_request(struct sctp_endpoint *ep, { int rc; struct netlbl_lsm_secattr secattr; - struct sk_security_struct *sksec = ep->base.sk->sk_security; + struct sk_security_struct *sksec = selinux_sock(ep->base.sk); struct sockaddr *addr; struct sockaddr_in addr4; #if IS_ENABLED(CONFIG_IPV6) @@ -370,7 +371,7 @@ int selinux_netlbl_inet_conn_request(struct request_sock *req, u16 family) */ void selinux_netlbl_inet_csk_clone(struct sock *sk, u16 family) { - struct sk_security_struct *sksec = sk->sk_security; + struct sk_security_struct *sksec = selinux_sock(sk); if (family == PF_INET) sksec->nlbl_state = NLBL_LABELED; @@ -388,8 +389,8 @@ void selinux_netlbl_inet_csk_clone(struct sock *sk, u16 family) */ void selinux_netlbl_sctp_sk_clone(struct sock *sk, struct sock *newsk) { - struct sk_security_struct *sksec = sk->sk_security; - struct sk_security_struct *newsksec = newsk->sk_security; + struct sk_security_struct *sksec = selinux_sock(sk); + struct sk_security_struct *newsksec = selinux_sock(newsk); newsksec->nlbl_state = sksec->nlbl_state; } @@ -407,7 +408,7 @@ void selinux_netlbl_sctp_sk_clone(struct sock *sk, struct sock *newsk) int selinux_netlbl_socket_post_create(struct sock *sk, u16 family) { int rc; - struct sk_security_struct *sksec = sk->sk_security; + struct sk_security_struct *sksec = selinux_sock(sk); struct netlbl_lsm_secattr *secattr; if (family != PF_INET && family != PF_INET6) @@ -522,7 +523,7 @@ int selinux_netlbl_socket_setsockopt(struct socket *sock, { int rc = 0; struct sock *sk = sock->sk; - struct sk_security_struct *sksec = sk->sk_security; + struct sk_security_struct *sksec = selinux_sock(sk); struct netlbl_lsm_secattr secattr; if (selinux_netlbl_option(level, optname) && @@ -560,7 +561,7 @@ static int selinux_netlbl_socket_connect_helper(struct sock *sk, struct sockaddr *addr) { int rc; - struct sk_security_struct *sksec = sk->sk_security; + struct sk_security_struct *sksec = selinux_sock(sk); struct netlbl_lsm_secattr *secattr; /* connected sockets are allowed to disconnect when the address family @@ -599,7 +600,7 @@ static int selinux_netlbl_socket_connect_helper(struct sock *sk, int selinux_netlbl_socket_connect_locked(struct sock *sk, struct sockaddr *addr) { - struct sk_security_struct *sksec = sk->sk_security; + struct sk_security_struct *sksec = selinux_sock(sk); if (sksec->nlbl_state != NLBL_REQSKB && sksec->nlbl_state != NLBL_CONNLABELED) diff --git a/security/smack/smack.h b/security/smack/smack.h index caecbcba9942..4ac4bf3310d7 100644 --- a/security/smack/smack.h +++ b/security/smack/smack.h @@ -375,6 +375,11 @@ static inline struct smack_known **smack_ipc(const struct kern_ipc_perm *ipc) return ipc->security + smack_blob_sizes.lbs_ipc; } +static inline struct socket_smack *smack_sock(const struct sock *sock) +{ + return sock->sk_security + smack_blob_sizes.lbs_sock; +} + static inline struct superblock_smack *smack_superblock( const struct super_block *superblock) { diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index 807eff2ccce9..fd69e1bd841b 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -1439,7 +1439,7 @@ static int smack_inode_getsecurity(struct inode *inode, if (sock == NULL || sock->sk == NULL) return -EOPNOTSUPP; - ssp = sock->sk->sk_security; + ssp = smack_sock(sock->sk); if (strcmp(name, XATTR_SMACK_IPIN) == 0) isp = ssp->smk_in; @@ -1821,7 +1821,7 @@ static int smack_file_receive(struct file *file) if (inode->i_sb->s_magic == SOCKFS_MAGIC) { sock = SOCKET_I(inode); - ssp = sock->sk->sk_security; + ssp = smack_sock(sock->sk); tsp = smack_cred(current_cred()); /* * If the receiving process can't write to the @@ -2231,11 +2231,7 @@ static void smack_task_to_inode(struct task_struct *p, struct inode *inode) static int smack_sk_alloc_security(struct sock *sk, int family, gfp_t gfp_flags) { struct smack_known *skp = smk_of_current(); - struct socket_smack *ssp; - - ssp = kzalloc(sizeof(struct socket_smack), gfp_flags); - if (ssp == NULL) - return -ENOMEM; + struct socket_smack *ssp = smack_sock(sk); /* * Sockets created by kernel threads receive web label. @@ -2249,11 +2245,10 @@ static int smack_sk_alloc_security(struct sock *sk, int family, gfp_t gfp_flags) } ssp->smk_packet = NULL; - sk->sk_security = ssp; - return 0; } +#ifdef SMACK_IPV6_PORT_LABELING /** * smack_sk_free_security - Free a socket blob * @sk: the socket @@ -2262,7 +2257,6 @@ static int smack_sk_alloc_security(struct sock *sk, int family, gfp_t gfp_flags) */ static void smack_sk_free_security(struct sock *sk) { -#ifdef SMACK_IPV6_PORT_LABELING struct smk_port_label *spp; if (sk->sk_family == PF_INET6) { @@ -2275,9 +2269,8 @@ static void smack_sk_free_security(struct sock *sk) } rcu_read_unlock(); } -#endif - kfree(sk->sk_security); } +#endif /** * smack_ipv4host_label - check host based restrictions @@ -2395,7 +2388,7 @@ static struct smack_known *smack_ipv6host_label(struct sockaddr_in6 *sip) static int smack_netlabel(struct sock *sk, int labeled) { struct smack_known *skp; - struct socket_smack *ssp = sk->sk_security; + struct socket_smack *ssp = smack_sock(sk); int rc = 0; /* @@ -2440,7 +2433,7 @@ static int smack_netlabel_send(struct sock *sk, struct sockaddr_in *sap) int rc; int sk_lbl; struct smack_known *hkp; - struct socket_smack *ssp = sk->sk_security; + struct socket_smack *ssp = smack_sock(sk); struct smk_audit_info ad; rcu_read_lock(); @@ -2516,7 +2509,7 @@ static void smk_ipv6_port_label(struct socket *sock, struct sockaddr *address) { struct sock *sk = sock->sk; struct sockaddr_in6 *addr6; - struct socket_smack *ssp = sock->sk->sk_security; + struct socket_smack *ssp = smack_sock(sock->sk); struct smk_port_label *spp; unsigned short port = 0; @@ -2603,7 +2596,7 @@ static int smk_ipv6_port_check(struct sock *sk, struct sockaddr_in6 *address, int act) { struct smk_port_label *spp; - struct socket_smack *ssp = sk->sk_security; + struct socket_smack *ssp = smack_sock(sk); struct smack_known *skp = NULL; unsigned short port; struct smack_known *object; @@ -2697,7 +2690,7 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name, if (sock == NULL || sock->sk == NULL) return -EOPNOTSUPP; - ssp = sock->sk->sk_security; + ssp = smack_sock(sock->sk); if (strcmp(name, XATTR_SMACK_IPIN) == 0) ssp->smk_in = skp; @@ -2745,7 +2738,7 @@ static int smack_socket_post_create(struct socket *sock, int family, * Sockets created by kernel threads receive web label. */ if (unlikely(current->flags & PF_KTHREAD)) { - ssp = sock->sk->sk_security; + ssp = smack_sock(sock->sk); ssp->smk_in = &smack_known_web; ssp->smk_out = &smack_known_web; } @@ -2770,8 +2763,8 @@ static int smack_socket_post_create(struct socket *sock, int family, static int smack_socket_socketpair(struct socket *socka, struct socket *sockb) { - struct socket_smack *asp = socka->sk->sk_security; - struct socket_smack *bsp = sockb->sk->sk_security; + struct socket_smack *asp = smack_sock(socka->sk); + struct socket_smack *bsp = smack_sock(sockb->sk); asp->smk_packet = bsp->smk_out; bsp->smk_packet = asp->smk_out; @@ -2825,7 +2818,7 @@ static int smack_socket_connect(struct socket *sock, struct sockaddr *sap, return 0; #ifdef SMACK_IPV6_SECMARK_LABELING - ssp = sock->sk->sk_security; + ssp = smack_sock(sock->sk); #endif switch (sock->sk->sk_family) { @@ -3566,9 +3559,9 @@ static int smack_unix_stream_connect(struct sock *sock, { struct smack_known *skp; struct smack_known *okp; - struct socket_smack *ssp = sock->sk_security; - struct socket_smack *osp = other->sk_security; - struct socket_smack *nsp = newsk->sk_security; + struct socket_smack *ssp = smack_sock(sock); + struct socket_smack *osp = smack_sock(other); + struct socket_smack *nsp = smack_sock(newsk); struct smk_audit_info ad; int rc = 0; #ifdef CONFIG_AUDIT @@ -3614,8 +3607,8 @@ static int smack_unix_stream_connect(struct sock *sock, */ static int smack_unix_may_send(struct socket *sock, struct socket *other) { - struct socket_smack *ssp = sock->sk->sk_security; - struct socket_smack *osp = other->sk->sk_security; + struct socket_smack *ssp = smack_sock(sock->sk); + struct socket_smack *osp = smack_sock(other->sk); struct smk_audit_info ad; int rc; @@ -3652,7 +3645,7 @@ static int smack_socket_sendmsg(struct socket *sock, struct msghdr *msg, struct sockaddr_in6 *sap = (struct sockaddr_in6 *) msg->msg_name; #endif #ifdef SMACK_IPV6_SECMARK_LABELING - struct socket_smack *ssp = sock->sk->sk_security; + struct socket_smack *ssp = smack_sock(sock->sk); struct smack_known *rsp; #endif int rc = 0; @@ -3817,7 +3810,7 @@ static int smk_skb_to_addr_ipv6(struct sk_buff *skb, struct sockaddr_in6 *sip) static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) { struct netlbl_lsm_secattr secattr; - struct socket_smack *ssp = sk->sk_security; + struct socket_smack *ssp = smack_sock(sk); struct smack_known *skp = NULL; int rc = 0; struct smk_audit_info ad; @@ -3934,7 +3927,7 @@ static int smack_socket_getpeersec_stream(struct socket *sock, int slen = 1; int rc = 0; - ssp = sock->sk->sk_security; + ssp = smack_sock(sock->sk); if (ssp->smk_packet != NULL) { rcp = ssp->smk_packet->smk_known; slen = strlen(rcp) + 1; @@ -3984,7 +3977,7 @@ static int smack_socket_getpeersec_dgram(struct socket *sock, switch (family) { case PF_UNIX: - ssp = sock->sk->sk_security; + ssp = smack_sock(sock->sk); s = ssp->smk_out->smk_secid; break; case PF_INET: @@ -3997,7 +3990,7 @@ static int smack_socket_getpeersec_dgram(struct socket *sock, * Translate what netlabel gave us. */ if (sock != NULL && sock->sk != NULL) - ssp = sock->sk->sk_security; + ssp = smack_sock(sock->sk); netlbl_secattr_init(&secattr); rc = netlbl_skbuff_getattr(skb, family, &secattr); if (rc == 0) { @@ -4035,7 +4028,7 @@ static void smack_sock_graft(struct sock *sk, struct socket *parent) (sk->sk_family != PF_INET && sk->sk_family != PF_INET6)) return; - ssp = sk->sk_security; + ssp = smack_sock(sk); ssp->smk_in = skp; ssp->smk_out = skp; /* cssp->smk_packet is already set in smack_inet_csk_clone() */ @@ -4055,7 +4048,7 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb, { u16 family = sk->sk_family; struct smack_known *skp; - struct socket_smack *ssp = sk->sk_security; + struct socket_smack *ssp = smack_sock(sk); struct netlbl_lsm_secattr secattr; struct sockaddr_in addr; struct iphdr *hdr; @@ -4154,7 +4147,7 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb, static void smack_inet_csk_clone(struct sock *sk, const struct request_sock *req) { - struct socket_smack *ssp = sk->sk_security; + struct socket_smack *ssp = smack_sock(sk); struct smack_known *skp; if (req->peer_secid != 0) { @@ -4558,6 +4551,7 @@ struct lsm_blob_sizes smack_blob_sizes __lsm_ro_after_init = { .lbs_inode = sizeof(struct inode_smack), .lbs_ipc = sizeof(struct smack_known *), .lbs_msg_msg = sizeof(struct smack_known *), + .lbs_sock = sizeof(struct socket_smack), .lbs_superblock = sizeof(struct superblock_smack), }; @@ -4667,7 +4661,9 @@ static struct security_hook_list smack_hooks[] __lsm_ro_after_init = { LSM_HOOK_INIT(socket_getpeersec_stream, smack_socket_getpeersec_stream), LSM_HOOK_INIT(socket_getpeersec_dgram, smack_socket_getpeersec_dgram), LSM_HOOK_INIT(sk_alloc_security, smack_sk_alloc_security), +#ifdef SMACK_IPV6_PORT_LABELING LSM_HOOK_INIT(sk_free_security, smack_sk_free_security), +#endif LSM_HOOK_INIT(sock_graft, smack_sock_graft), LSM_HOOK_INIT(inet_conn_request, smack_inet_conn_request), LSM_HOOK_INIT(inet_csk_clone, smack_inet_csk_clone), diff --git a/security/smack/smack_netfilter.c b/security/smack/smack_netfilter.c index e36d17835d4f..701a1cc1bdcc 100644 --- a/security/smack/smack_netfilter.c +++ b/security/smack/smack_netfilter.c @@ -31,8 +31,8 @@ static unsigned int smack_ipv6_output(void *priv, struct socket_smack *ssp; struct smack_known *skp; - if (sk && sk->sk_security) { - ssp = sk->sk_security; + if (sk && smack_sock(sk)) { + ssp = smack_sock(sk); skp = ssp->smk_out; skb->secmark = skp->smk_secid; } @@ -49,8 +49,8 @@ static unsigned int smack_ipv4_output(void *priv, struct socket_smack *ssp; struct smack_known *skp; - if (sk && sk->sk_security) { - ssp = sk->sk_security; + if (sk && smack_sock(sk)) { + ssp = smack_sock(sk); skp = ssp->smk_out; skb->secmark = skp->smk_secid; } From patchwork Thu Aug 29 23:29:10 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 11122589 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id D0D141395 for ; Thu, 29 Aug 2019 23:29:45 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id A534321874 for ; Thu, 29 Aug 2019 23:29:45 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="ANb539eV" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1725999AbfH2X3p (ORCPT ); Thu, 29 Aug 2019 19:29:45 -0400 Received: from sonic307-16.consmr.mail.ne1.yahoo.com ([66.163.190.39]:40229 "EHLO sonic307-16.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726014AbfH2X3o (ORCPT ); Thu, 29 Aug 2019 19:29:44 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1567121382; bh=uDaZK+tmy6XVn6IfwbbUA4ENbB2YjAReMXHmAiytrSQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=ANb539eVoicU0TufAVT5Xa7SbXw8zxtNiC4EKFX84+Br+G3/FiWHlg+3E1Zt5OiMzIY08zEDtQ084qHJj9Myt8MrM8gg9HDPeMpN7j+ofu+HpQu2BScHvBNQela5wyMLXZIQ8fufMW4YAHdPa2tttSj6YRPd1A5TvngXL0LioUhgFy+ksAfqkLTncQSWb//wWpDK34qcgbApTWjqpFD5wQR3DbOIvXMZEjuPJ2v/u5e4AuVEHz61MBQo+lSdScbyuX8n5+5/ZyDYNuQLLg8t3+pnk/UvUAzsD5XTH7QqufaWRDHqIVAfiWqCk4Ab5YeaBhJf5UAv3giqFglrzQzxSw== X-YMail-OSG: e3jEAgEVM1ndyBeEcIJzL1D.CoxRiIl.p2kkM8Vycz2b9Gz88NgTUOix0NG1qoq aoZPtmIKg9OdcYmWftG0Pdg4UQpp1ux23pDRB1fdO7qbqwHFIENpu1HZd6McIa5oGX.JI.HYPD9c l54esO1fcVbiYaoi.mH6JafaCd5o3KVEaASOdOhCDB.qumHRBqRMwr8jmZQJv7mxnLf2W6h8O4Sr tAlIf1YIaZYLZNgSXFdejCq2p26f_k0h5T1N1YxKuUkd9laUeQn2lWVvYmsNilHz.v8oVK6nNkCV v5Pjqrkv.lKXNCbMrhX0I0BaFC9DPcZLyJh7k.OF1N1SrY4YCslLsy_Q0xeblQ20KrrEvp2q2iOp _NXtd_Y8A5hRrBP9DMLZSB8gswSs0MmKcS2fAQB.v1cfdpMjrND2CulymEG_MxAPRl6mJd4ew2bX ZIH.BNPTJAqeaciQ1lBImnjWxvHBwXuIuaieqMhIQ9ewD0eVzUvO8uptwxf_4ekPcK5alHU2SJ.p sgCAXNh6iJ1nzS2X0q3OvuDHwyfFjEg_TOZmKgJyLALtXIy0DuulVMGBR6Z66sBfJZdcYFiqLRcy qHkDmzdtnLKfclxemv2ZlehkF4Z0wDYUiq_jrG.GsOihP.r_H_qYYhMI6fSX01E3CAYbQbmk6h3o 2nuwIaxgiDLYH7fgQJFvR5vVvtGCXe9GBVN_vl59XUWT3AwvxsfI_D_5KT9U.kDX6JI5z05smCWG zkmGpe5MQ2fg0jBWV9D2HV7nlWBQfbWe18pPY7Nhgxz1bbi91TrTFVqsbDTJrsYFuCu.I_Eh5t4U I1GysaQYSfAsYMDarXZL.1jbtc7fFWTjRj7.9lsZhP_hLmbFN3yrv58Bkpoaa0yVy6iRkXkgHMfj IUPXbZtZ78L99RwGIE2HwVJqJrnoLpS24FeMJ1U_hqo4uBAWBdLQJN5Qp9Hm4l_i.1_XaFjNfJhY eoJyvdwmGW_y7YGfoar7sss0oRccXToa_wI6qx.M.lhfJjMYcYcT2jD3e6SxxJPuPgRUfxtKwnxj DE31G4E9asYejFBk8939i8MS_5QWwi0t20HiTrtbkUFK5wd2DCxCl0eUuoNrprXtNsmbcztenyT4 8rP948sajTeo64ERyImON93x33iTVPEy34sjvRPZfzDtAYBWQ5FjzgRdNNvZE6rHZH84rCfiQtH4 6xyse5.FlevRWKPB3_JhD8ll9tgKpPPZeZD_nmwMKJdMyY6hPtJ1jiOPh5xtNX4f0ZmEsC0U3Kfl rKYGM6K7muC175i3X0ZyrZl9Rlihivq2C7zP_iW1HV1K6ro7BWznPppKJZrlsvVJr3NWSVlxRMDL uc436XhY- Received: from sonic.gate.mail.ne1.yahoo.com by sonic307.consmr.mail.ne1.yahoo.com with HTTP; Thu, 29 Aug 2019 23:29:42 +0000 Received: by smtp403.mail.ne1.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID 348e1bb830015a550a7ef552e960420a; Thu, 29 Aug 2019 23:29:40 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, jmorris@namei.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org Cc: casey@schaufler-ca.com, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, paul@paul-moore.com, sds@tycho.nsa.gov Subject: [PATCH v8 03/28] LSM: Infrastructure management of the key blob Date: Thu, 29 Aug 2019 16:29:10 -0700 Message-Id: <20190829232935.7099-4-casey@schaufler-ca.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190829232935.7099-1-casey@schaufler-ca.com> References: <20190829232935.7099-1-casey@schaufler-ca.com> MIME-Version: 1.0 Sender: selinux-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: selinux@vger.kernel.org From: Casey Schaufler Move management of the key->security blob out of the individual security modules and into the security infrastructure. Instead of allocating the blobs from within the modules the modules tell the infrastructure how much space is required, and the space is allocated there. Reviewed-by: Kees Cook Reviewed-by: John Johansen Signed-off-by: Casey Schaufler Reviewed-by: Stephen Smalley --- include/linux/lsm_hooks.h | 1 + security/security.c | 40 ++++++++++++++++++++++++++++++- security/selinux/hooks.c | 23 +++++------------- security/selinux/include/objsec.h | 7 ++++++ security/smack/smack.h | 7 ++++++ security/smack/smack_lsm.c | 33 ++++++++++++------------- 6 files changed, 75 insertions(+), 36 deletions(-) diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h index b353482ea348..3fe39abccc8f 100644 --- a/include/linux/lsm_hooks.h +++ b/include/linux/lsm_hooks.h @@ -2050,6 +2050,7 @@ struct lsm_blob_sizes { int lbs_sock; int lbs_superblock; int lbs_ipc; + int lbs_key; int lbs_msg_msg; int lbs_task; }; diff --git a/security/security.c b/security/security.c index 2c0834db7976..7cfedb90210a 100644 --- a/security/security.c +++ b/security/security.c @@ -172,6 +172,9 @@ static void __init lsm_set_blob_sizes(struct lsm_blob_sizes *needed) blob_sizes.lbs_inode = sizeof(struct rcu_head); lsm_set_blob_size(&needed->lbs_inode, &blob_sizes.lbs_inode); lsm_set_blob_size(&needed->lbs_ipc, &blob_sizes.lbs_ipc); +#ifdef CONFIG_KEYS + lsm_set_blob_size(&needed->lbs_key, &blob_sizes.lbs_key); +#endif lsm_set_blob_size(&needed->lbs_msg_msg, &blob_sizes.lbs_msg_msg); lsm_set_blob_size(&needed->lbs_sock, &blob_sizes.lbs_sock); lsm_set_blob_size(&needed->lbs_superblock, &blob_sizes.lbs_superblock); @@ -307,6 +310,9 @@ static void __init ordered_lsm_init(void) init_debug("file blob size = %d\n", blob_sizes.lbs_file); init_debug("inode blob size = %d\n", blob_sizes.lbs_inode); init_debug("ipc blob size = %d\n", blob_sizes.lbs_ipc); +#ifdef CONFIG_KEYS + init_debug("key blob size = %d\n", blob_sizes.lbs_key); +#endif /* CONFIG_KEYS */ init_debug("msg_msg blob size = %d\n", blob_sizes.lbs_msg_msg); init_debug("sock blob size = %d\n", blob_sizes.lbs_sock); init_debug("superblock blob size = %d\n", blob_sizes.lbs_superblock); @@ -573,6 +579,29 @@ static int lsm_ipc_alloc(struct kern_ipc_perm *kip) return 0; } +#ifdef CONFIG_KEYS +/** + * lsm_key_alloc - allocate a composite key blob + * @key: the key that needs a blob + * + * Allocate the key blob for all the modules + * + * Returns 0, or -ENOMEM if memory can't be allocated. + */ +static int lsm_key_alloc(struct key *key) +{ + if (blob_sizes.lbs_key == 0) { + key->security = NULL; + return 0; + } + + key->security = kzalloc(blob_sizes.lbs_key, GFP_KERNEL); + if (key->security == NULL) + return -ENOMEM; + return 0; +} +#endif /* CONFIG_KEYS */ + /** * lsm_msg_msg_alloc - allocate a composite msg_msg blob * @mp: the msg_msg that needs a blob @@ -2339,12 +2368,21 @@ EXPORT_SYMBOL(security_skb_classify_flow); int security_key_alloc(struct key *key, const struct cred *cred, unsigned long flags) { - return call_int_hook(key_alloc, 0, key, cred, flags); + int rc = lsm_key_alloc(key); + + if (unlikely(rc)) + return rc; + rc = call_int_hook(key_alloc, 0, key, cred, flags); + if (unlikely(rc)) + security_key_free(key); + return rc; } void security_key_free(struct key *key) { call_void_hook(key_free, key); + kfree(key->security); + key->security = NULL; } int security_key_permission(key_ref_t key_ref, diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 5d74ed35b728..c83ec2652eda 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -6353,11 +6353,7 @@ static int selinux_key_alloc(struct key *k, const struct cred *cred, unsigned long flags) { const struct task_security_struct *tsec; - struct key_security_struct *ksec; - - ksec = kzalloc(sizeof(struct key_security_struct), GFP_KERNEL); - if (!ksec) - return -ENOMEM; + struct key_security_struct *ksec = selinux_key(k); tsec = selinux_cred(cred); if (tsec->keycreate_sid) @@ -6365,18 +6361,9 @@ static int selinux_key_alloc(struct key *k, const struct cred *cred, else ksec->sid = tsec->sid; - k->security = ksec; return 0; } -static void selinux_key_free(struct key *k) -{ - struct key_security_struct *ksec = k->security; - - k->security = NULL; - kfree(ksec); -} - static int selinux_key_permission(key_ref_t key_ref, const struct cred *cred, unsigned perm) @@ -6394,7 +6381,7 @@ static int selinux_key_permission(key_ref_t key_ref, sid = cred_sid(cred); key = key_ref_to_ptr(key_ref); - ksec = key->security; + ksec = selinux_key(key); return avc_has_perm(&selinux_state, sid, ksec->sid, SECCLASS_KEY, perm, NULL); @@ -6402,7 +6389,7 @@ static int selinux_key_permission(key_ref_t key_ref, static int selinux_key_getsecurity(struct key *key, char **_buffer) { - struct key_security_struct *ksec = key->security; + struct key_security_struct *ksec = selinux_key(key); char *context = NULL; unsigned len; int rc; @@ -6627,6 +6614,9 @@ struct lsm_blob_sizes selinux_blob_sizes __lsm_ro_after_init = { .lbs_file = sizeof(struct file_security_struct), .lbs_inode = sizeof(struct inode_security_struct), .lbs_ipc = sizeof(struct ipc_security_struct), +#ifdef CONFIG_KEYS + .lbs_key = sizeof(struct key_security_struct), +#endif /* CONFIG_KEYS */ .lbs_msg_msg = sizeof(struct msg_security_struct), .lbs_sock = sizeof(struct sk_security_struct), .lbs_superblock = sizeof(struct superblock_security_struct), @@ -6842,7 +6832,6 @@ static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = { #ifdef CONFIG_KEYS LSM_HOOK_INIT(key_alloc, selinux_key_alloc), - LSM_HOOK_INIT(key_free, selinux_key_free), LSM_HOOK_INIT(key_permission, selinux_key_permission), LSM_HOOK_INIT(key_getsecurity, selinux_key_getsecurity), #endif diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h index 29f02b8f8f31..3b78aa4ee98f 100644 --- a/security/selinux/include/objsec.h +++ b/security/selinux/include/objsec.h @@ -194,6 +194,13 @@ static inline struct superblock_security_struct *selinux_superblock( return superblock->s_security + selinux_blob_sizes.lbs_superblock; } +#ifdef CONFIG_KEYS +static inline struct key_security_struct *selinux_key(const struct key *key) +{ + return key->security + selinux_blob_sizes.lbs_key; +} +#endif /* CONFIG_KEYS */ + static inline struct sk_security_struct *selinux_sock(const struct sock *sock) { return sock->sk_security + selinux_blob_sizes.lbs_sock; diff --git a/security/smack/smack.h b/security/smack/smack.h index 4ac4bf3310d7..7cc3a3382fee 100644 --- a/security/smack/smack.h +++ b/security/smack/smack.h @@ -386,6 +386,13 @@ static inline struct superblock_smack *smack_superblock( return superblock->s_security + smack_blob_sizes.lbs_superblock; } +#ifdef CONFIG_KEYS +static inline struct smack_known **smack_key(const struct key *key) +{ + return key->security + smack_blob_sizes.lbs_key; +} +#endif /* CONFIG_KEYS */ + /* * Is the directory transmuting? */ diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index fd69e1bd841b..e9560b078efe 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -4179,23 +4179,13 @@ static void smack_inet_csk_clone(struct sock *sk, static int smack_key_alloc(struct key *key, const struct cred *cred, unsigned long flags) { + struct smack_known **blob = smack_key(key); struct smack_known *skp = smk_of_task(smack_cred(cred)); - key->security = skp; + *blob = skp; return 0; } -/** - * smack_key_free - Clear the key security blob - * @key: the object - * - * Clear the blob pointer - */ -static void smack_key_free(struct key *key) -{ - key->security = NULL; -} - /** * smack_key_permission - Smack access on a key * @key_ref: gets to the object @@ -4208,6 +4198,8 @@ static void smack_key_free(struct key *key) static int smack_key_permission(key_ref_t key_ref, const struct cred *cred, unsigned perm) { + struct smack_known **blob; + struct smack_known *skp; struct key *keyp; struct smk_audit_info ad; struct smack_known *tkp = smk_of_task(smack_cred(cred)); @@ -4227,7 +4219,9 @@ static int smack_key_permission(key_ref_t key_ref, * If the key hasn't been initialized give it access so that * it may do so. */ - if (keyp->security == NULL) + blob = smack_key(keyp); + skp = *blob; + if (skp == NULL) return 0; /* * This should not occur @@ -4247,8 +4241,8 @@ static int smack_key_permission(key_ref_t key_ref, request |= MAY_READ; if (perm & (KEY_NEED_WRITE | KEY_NEED_LINK | KEY_NEED_SETATTR)) request |= MAY_WRITE; - rc = smk_access(tkp, keyp->security, request, &ad); - rc = smk_bu_note("key access", tkp, keyp->security, request, rc); + rc = smk_access(tkp, skp, request, &ad); + rc = smk_bu_note("key access", tkp, skp, request, rc); return rc; } @@ -4263,11 +4257,12 @@ static int smack_key_permission(key_ref_t key_ref, */ static int smack_key_getsecurity(struct key *key, char **_buffer) { - struct smack_known *skp = key->security; + struct smack_known **blob = smack_key(key); + struct smack_known *skp = *blob; size_t length; char *copy; - if (key->security == NULL) { + if (skp == NULL) { *_buffer = NULL; return 0; } @@ -4550,6 +4545,9 @@ struct lsm_blob_sizes smack_blob_sizes __lsm_ro_after_init = { .lbs_file = sizeof(struct smack_known *), .lbs_inode = sizeof(struct inode_smack), .lbs_ipc = sizeof(struct smack_known *), +#ifdef CONFIG_KEYS + .lbs_key = sizeof(struct smack_known *), +#endif /* CONFIG_KEYS */ .lbs_msg_msg = sizeof(struct smack_known *), .lbs_sock = sizeof(struct socket_smack), .lbs_superblock = sizeof(struct superblock_smack), @@ -4671,7 +4669,6 @@ static struct security_hook_list smack_hooks[] __lsm_ro_after_init = { /* key management security hooks */ #ifdef CONFIG_KEYS LSM_HOOK_INIT(key_alloc, smack_key_alloc), - LSM_HOOK_INIT(key_free, smack_key_free), LSM_HOOK_INIT(key_permission, smack_key_permission), LSM_HOOK_INIT(key_getsecurity, smack_key_getsecurity), #endif /* CONFIG_KEYS */ From patchwork Thu Aug 29 23:29:11 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 11122595 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id EBA1D14E5 for ; Thu, 29 Aug 2019 23:29:47 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id C07DD21874 for ; Thu, 29 Aug 2019 23:29:47 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="TpslpB4c" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726369AbfH2X3r (ORCPT ); Thu, 29 Aug 2019 19:29:47 -0400 Received: from sonic311-31.consmr.mail.ne1.yahoo.com ([66.163.188.212]:45807 "EHLO sonic311-31.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725848AbfH2X3p (ORCPT ); Thu, 29 Aug 2019 19:29:45 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1567121381; bh=BjNumHharfDX8EfOP+ozMcC7Xiw5F55es9oKG7iaG9E=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=TpslpB4cMRRHFCTErq0DRRuRj6qdBVzeHkv1py0M/6ZoF6hUD+5j28fI+rIxTnw2F5s9LK8O33AMBu3mJ8mb1V4Lv79VaWo6ddbmwjLyoq1Q/DXgOSHg1qCjQf+Yfr9LHkztHlBizce6KMzPnnhIiQafAqwUWQGpOZZ8P4IIPDjolQ6GLHqgdRO/ikIKqbbH947p59PcFh+zb81fU0JtZdM6F2MskMNJZy0aB3Lr8iOV+r6CIN525dxlbrBqOaA3DHGEjzT8RnF5R+IfvXkPy2BL0GpmTlbd9c9SyN0ZNYMlrUvWSwVhjAiyBEKRyBcbL/xjxTayCWC+yFKhhh0Rzw== X-YMail-OSG: SndxPw4VM1l0PR5F1Cd2LuatfUgIJy_NMIeZOLvkhE9hdz6C6TzG1NWJTBd96mX Z3YFKJmLEHC9DjMyNGlyHRnQqCLtSbNjJBaQhGKFJ.28Ihu3xshoskRBQGKKRNFdRmg9O21A2cNd Pz.YLpB0ARVnZFy7iaXKaNsbkew.G6atiw0efCk0j_QY7oYTbwbtXVjNN7aYQ2hZhwHRBXXMmkJb 0lntWh0BswwPiV.0b1KSADTaVRbzlUNRwhsYz5R5xagkM3rdlYv5M_6l38Y7q7OyQV.4q_1ELnCu s5p9DvtsUe1feUe9pA8d76TtNhUMYYjjjqq.gxxKQRlrEBZESFmDMTyI3gvPsVOSYaZ4wi3o7Q9q XgpWFL9Q9pmKuEOIpz2s7RQH5iGkbF_PwyfoIjMbd9rhiEziwTVvHONPNXXScgTMKBW71uzfql8C Gm7udoDTbSuSr7_3PNXgD4UQtcUX57IRP_1a93p2Kevs7tGdXu6HWfWsiYreGAlWjaJvb8dKLNw8 SynMADwYpvuS.bSFAzsjS5k4HvxdyuBGo2Ef0VxRoLu0lHlVvTW0cQK70j2mtwza_QqnNFH29Gk0 ov1DfUWd.94yL4bCUmLTG25qDJfj8l60HUK21w8yt2zGCq4cIjdQ0ljP9urkfuLj7I0MIT7WFppA QeKbE6NvUorOG7aZs08kJh8wA6azBRo6ZIkEJbjCu.cX4eu2eRiHORV4kFz42yuzKAvo1kQdvcgK cbSlBkjlvTXCmMh._BNDYDobq3QURiRw._W_TSumNJyzALCXLjzkT1s7CB6EMiZUBMdRyniFiZFP hUlZ3dJn00pEynvOE.J0yqwZMqBfvVwqJyOHaGzQgVcqETNfZcZkIA3.EgrASCildNpTGYnZndKA DPNrfqKPiNngKC_RTiWt9nQV9xw_cwopxvNfBNklukndI7_A4IMUwwCGVY0fxlDUps02LSvEverZ HDfwwFZTl0HDF._NZmz3S1UCyUgvj1RTlr.47LU45MEG5ZRuw5s4Ts0lwOel8i112c1KyMDDq07Z KDDrmc3yYKvA3ZhvgzQiwtHF.nvZl.AtIFdUPhAzk1uDXFY6VHMxy5TBL77vBOU7lL_nkpwAO8Ou TH8tSRRUPtW_MVgXKQrhG2wROxE.my8u1reOtGoykUi0Du.teH1VYcaElAe9GcNEM02WeEGI16yA v3jMvr4yc24CYmXQx_XRbv.vedTKtHvIgNEsd4WHeOSJVe1tyIGHXqpqb7Cdu4UZgDFnFmAKhlUq Y3QN304eYt_xpEifaNoLoFjb6AgtOW6jyc_xqyfVcrggIhIUCuT1Qv_724OvRvZOClnB53t8M58e MQi3U..I- Received: from sonic.gate.mail.ne1.yahoo.com by sonic311.consmr.mail.ne1.yahoo.com with HTTP; Thu, 29 Aug 2019 23:29:41 +0000 Received: by smtp403.mail.ne1.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID 348e1bb830015a550a7ef552e960420a; Thu, 29 Aug 2019 23:29:40 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, jmorris@namei.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org Cc: casey@schaufler-ca.com, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, paul@paul-moore.com, sds@tycho.nsa.gov Subject: [PATCH v8 04/28] LSM: Create and manage the lsmblob data structure. Date: Thu, 29 Aug 2019 16:29:11 -0700 Message-Id: <20190829232935.7099-5-casey@schaufler-ca.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190829232935.7099-1-casey@schaufler-ca.com> References: <20190829232935.7099-1-casey@schaufler-ca.com> MIME-Version: 1.0 Sender: selinux-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: selinux@vger.kernel.org When more than one security module is exporting data to audit and networking sub-systems a single 32 bit integer is no longer sufficient to represent the data. Add a structure to be used instead. The lsmblob structure is currently an array of u32 "secids". There is an entry for each of the security modules built into the system that would use secids if active. The system assigns the module a "slot" when it registers hooks. If modules are compiled in but not registered there will be unused slots. A new lsm_id structure, which contains the name of the LSM and its slot number, is created. There is an instance for each LSM, which assigns the name and passes it to the infrastructure to set the slot. Reviewed-by: Kees Cook Reviewed-by: John Johansen Signed-off-by: Casey Schaufler --- include/linux/lsm_hooks.h | 12 +++++-- include/linux/security.h | 66 ++++++++++++++++++++++++++++++++++++++ security/apparmor/lsm.c | 7 +++- security/commoncap.c | 7 +++- security/loadpin/loadpin.c | 8 ++++- security/safesetid/lsm.c | 8 ++++- security/security.c | 31 ++++++++++++++---- security/selinux/hooks.c | 8 ++++- security/smack/smack_lsm.c | 7 +++- security/tomoyo/tomoyo.c | 8 ++++- security/yama/yama_lsm.c | 7 +++- 11 files changed, 152 insertions(+), 17 deletions(-) diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h index 3fe39abccc8f..fe1fb7a69ee5 100644 --- a/include/linux/lsm_hooks.h +++ b/include/linux/lsm_hooks.h @@ -2029,6 +2029,14 @@ struct security_hook_heads { #endif /* CONFIG_BPF_SYSCALL */ } __randomize_layout; +/* + * Information that identifies a security module. + */ +struct lsm_id { + const char *lsm; /* Name of the LSM */ + int slot; /* Slot in lsmblob if one is allocated */ +}; + /* * Security module hook list structure. * For use with generic list macros for common operations. @@ -2037,7 +2045,7 @@ struct security_hook_list { struct hlist_node list; struct hlist_head *head; union security_list_options hook; - char *lsm; + struct lsm_id *lsmid; } __randomize_layout; /* @@ -2068,7 +2076,7 @@ extern struct security_hook_heads security_hook_heads; extern char *lsm_names; extern void security_add_hooks(struct security_hook_list *hooks, int count, - char *lsm); + struct lsm_id *lsmid); #define LSM_FLAG_LEGACY_MAJOR BIT(0) #define LSM_FLAG_EXCLUSIVE BIT(1) diff --git a/include/linux/security.h b/include/linux/security.h index 49f2685324b0..5bb8b9a6fa84 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -76,6 +76,72 @@ enum lsm_event { LSM_POLICY_CHANGE, }; +/* + * Data exported by the security modules + * + * Any LSM that provides secid or secctx based hooks must be included. + */ +#define LSMBLOB_ENTRIES ( \ + (IS_ENABLED(CONFIG_SECURITY_SELINUX) ? 1 : 0) + \ + (IS_ENABLED(CONFIG_SECURITY_SMACK) ? 1 : 0) + \ + (IS_ENABLED(CONFIG_SECURITY_APPARMOR) ? 1 : 0)) + +struct lsmblob { + u32 secid[LSMBLOB_ENTRIES]; +}; + +#define LSMBLOB_INVALID -1 /* Not a valid LSM slot number */ +#define LSMBLOB_NEEDED -2 /* Slot requested on initialization */ +#define LSMBLOB_NOT_NEEDED -3 /* Slot not requested */ + +/** + * lsmblob_init - initialize an lsmblob structure. + * @blob: Pointer to the data to initialize + * @secid: The initial secid value + * + * Set all secid for all modules to the specified value. + */ +static inline void lsmblob_init(struct lsmblob *blob, u32 secid) +{ + int i; + + for (i = 0; i < LSMBLOB_ENTRIES; i++) + blob->secid[i] = secid; +} + +/** + * lsmblob_is_set - report if there is an value in the lsmblob + * @blob: Pointer to the exported LSM data + * + * Returns true if there is a secid set, false otherwise + */ +static inline bool lsmblob_is_set(struct lsmblob *blob) +{ + int i; + + for (i = 0; i < LSMBLOB_ENTRIES; i++) + if (blob->secid[i] != 0) + return true; + return false; +} + +/** + * lsmblob_equal - report if the two lsmblob's are equal + * @bloba: Pointer to one LSM data + * @blobb: Pointer to the other LSM data + * + * Returns true if all entries in the two are equal, false otherwise + */ +static inline bool lsmblob_equal(struct lsmblob *bloba, struct lsmblob *blobb) +{ + int i; + + for (i = 0; i < LSMBLOB_ENTRIES; i++) + if (bloba->secid[i] != blobb->secid[i]) + return false; + return true; +} + /* These functions are in security/commoncap.c */ extern int cap_capable(const struct cred *cred, struct user_namespace *ns, int cap, unsigned int opts); diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c index 2716e7731279..ec2e39aa9a84 100644 --- a/security/apparmor/lsm.c +++ b/security/apparmor/lsm.c @@ -1138,6 +1138,11 @@ struct lsm_blob_sizes apparmor_blob_sizes __lsm_ro_after_init = { .lbs_sock = sizeof(struct aa_sk_ctx), }; +static struct lsm_id apparmor_lsmid __lsm_ro_after_init = { + .lsm = "apparmor", + .slot = LSMBLOB_NEEDED +}; + static struct security_hook_list apparmor_hooks[] __lsm_ro_after_init = { LSM_HOOK_INIT(ptrace_access_check, apparmor_ptrace_access_check), LSM_HOOK_INIT(ptrace_traceme, apparmor_ptrace_traceme), @@ -1679,7 +1684,7 @@ static int __init apparmor_init(void) goto buffers_out; } security_add_hooks(apparmor_hooks, ARRAY_SIZE(apparmor_hooks), - "apparmor"); + &apparmor_lsmid); /* Report that AppArmor successfully initialized */ apparmor_initialized = 1; diff --git a/security/commoncap.c b/security/commoncap.c index afd9679ca866..973e6c7009d0 100644 --- a/security/commoncap.c +++ b/security/commoncap.c @@ -1344,6 +1344,11 @@ int cap_mmap_file(struct file *file, unsigned long reqprot, #ifdef CONFIG_SECURITY +static struct lsm_id capability_lsmid __lsm_ro_after_init = { + .lsm = "capability", + .slot = LSMBLOB_NOT_NEEDED +}; + static struct security_hook_list capability_hooks[] __lsm_ro_after_init = { LSM_HOOK_INIT(capable, cap_capable), LSM_HOOK_INIT(settime, cap_settime), @@ -1368,7 +1373,7 @@ static struct security_hook_list capability_hooks[] __lsm_ro_after_init = { static int __init capability_init(void) { security_add_hooks(capability_hooks, ARRAY_SIZE(capability_hooks), - "capability"); + &capability_lsmid); return 0; } diff --git a/security/loadpin/loadpin.c b/security/loadpin/loadpin.c index 055fb0a64169..7b23fdf24e27 100644 --- a/security/loadpin/loadpin.c +++ b/security/loadpin/loadpin.c @@ -181,6 +181,11 @@ static int loadpin_load_data(enum kernel_load_data_id id) return loadpin_read_file(NULL, (enum kernel_read_file_id) id); } +static struct lsm_id loadpin_lsmid __lsm_ro_after_init = { + .lsm = "loadpin", + .slot = LSMBLOB_NOT_NEEDED +}; + static struct security_hook_list loadpin_hooks[] __lsm_ro_after_init = { LSM_HOOK_INIT(sb_free_security, loadpin_sb_free_security), LSM_HOOK_INIT(kernel_read_file, loadpin_read_file), @@ -191,7 +196,8 @@ static int __init loadpin_init(void) { pr_info("ready to pin (currently %senforcing)\n", enforce ? "" : "not "); - security_add_hooks(loadpin_hooks, ARRAY_SIZE(loadpin_hooks), "loadpin"); + security_add_hooks(loadpin_hooks, ARRAY_SIZE(loadpin_hooks), + &loadpin_lsmid); return 0; } diff --git a/security/safesetid/lsm.c b/security/safesetid/lsm.c index cecd38e2ac80..4a96cd8c0d15 100644 --- a/security/safesetid/lsm.c +++ b/security/safesetid/lsm.c @@ -255,6 +255,11 @@ void flush_safesetid_whitelist_entries(void) } } +static struct lsm_id safesetid_lsmid __lsm_ro_after_init = { + .lsm = "safesetid", + .slot = LSMBLOB_NOT_NEEDED +}; + static struct security_hook_list safesetid_security_hooks[] = { LSM_HOOK_INIT(task_fix_setuid, safesetid_task_fix_setuid), LSM_HOOK_INIT(capable, safesetid_security_capable) @@ -263,7 +268,8 @@ static struct security_hook_list safesetid_security_hooks[] = { static int __init safesetid_security_init(void) { security_add_hooks(safesetid_security_hooks, - ARRAY_SIZE(safesetid_security_hooks), "safesetid"); + ARRAY_SIZE(safesetid_security_hooks), + &safesetid_lsmid); /* Report that SafeSetID successfully initialized */ safesetid_initialized = 1; diff --git a/security/security.c b/security/security.c index 7cfedb90210a..27e2db3d6b04 100644 --- a/security/security.c +++ b/security/security.c @@ -317,6 +317,7 @@ static void __init ordered_lsm_init(void) init_debug("sock blob size = %d\n", blob_sizes.lbs_sock); init_debug("superblock blob size = %d\n", blob_sizes.lbs_superblock); init_debug("task blob size = %d\n", blob_sizes.lbs_task); + init_debug("lsmblob size = %lu\n", sizeof(struct lsmblob)); /* * Create any kmem_caches needed for blobs @@ -399,7 +400,7 @@ static bool match_last_lsm(const char *list, const char *lsm) return !strcmp(last, lsm); } -static int lsm_append(char *new, char **result) +static int lsm_append(const char *new, char **result) { char *cp; @@ -420,24 +421,40 @@ static int lsm_append(char *new, char **result) return 0; } +/* + * Current index to use while initializing the lsmblob secid list. + */ +static int lsm_slot __initdata; + /** * security_add_hooks - Add a modules hooks to the hook lists. * @hooks: the hooks to add * @count: the number of hooks to add - * @lsm: the name of the security module + * @lsmid: the identification information for the security module * * Each LSM has to register its hooks with the infrastructure. + * If the LSM is using hooks that export secids allocate a slot + * for it in the lsmblob. */ void __init security_add_hooks(struct security_hook_list *hooks, int count, - char *lsm) + struct lsm_id *lsmid) { int i; + if (lsmid->slot == LSMBLOB_NEEDED) { + if (lsm_slot >= LSMBLOB_ENTRIES) + panic("%s Too many LSMs registered.\n", __func__); + lsmid->slot = lsm_slot++; + init_debug("%s assigned lsmblob slot %d\n", lsmid->lsm, + lsmid->slot); + } + for (i = 0; i < count; i++) { - hooks[i].lsm = lsm; + hooks[i].lsmid = lsmid; hlist_add_tail_rcu(&hooks[i].list, hooks[i].head); } - if (lsm_append(lsm, &lsm_names) < 0) + + if (lsm_append(lsmid->lsm, &lsm_names) < 0) panic("%s - Cannot get early memory.\n", __func__); } @@ -1917,7 +1934,7 @@ int security_getprocattr(struct task_struct *p, const char *lsm, char *name, struct security_hook_list *hp; hlist_for_each_entry(hp, &security_hook_heads.getprocattr, list) { - if (lsm != NULL && strcmp(lsm, hp->lsm)) + if (lsm != NULL && strcmp(lsm, hp->lsmid->lsm)) continue; return hp->hook.getprocattr(p, name, value); } @@ -1930,7 +1947,7 @@ int security_setprocattr(const char *lsm, const char *name, void *value, struct security_hook_list *hp; hlist_for_each_entry(hp, &security_hook_heads.setprocattr, list) { - if (lsm != NULL && strcmp(lsm, hp->lsm)) + if (lsm != NULL && strcmp(lsm, hp->lsmid->lsm)) continue; return hp->hook.setprocattr(name, value, size); } diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index c83ec2652eda..74c491980ed2 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -6622,6 +6622,11 @@ struct lsm_blob_sizes selinux_blob_sizes __lsm_ro_after_init = { .lbs_superblock = sizeof(struct superblock_security_struct), }; +static struct lsm_id selinux_lsmid __lsm_ro_after_init = { + .lsm = "selinux", + .slot = LSMBLOB_NEEDED +}; + static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = { LSM_HOOK_INIT(binder_set_context_mgr, selinux_binder_set_context_mgr), LSM_HOOK_INIT(binder_transaction, selinux_binder_transaction), @@ -6877,7 +6882,8 @@ static __init int selinux_init(void) hashtab_cache_init(); - security_add_hooks(selinux_hooks, ARRAY_SIZE(selinux_hooks), "selinux"); + security_add_hooks(selinux_hooks, ARRAY_SIZE(selinux_hooks), + &selinux_lsmid); if (avc_add_callback(selinux_netcache_avc_callback, AVC_CALLBACK_RESET)) panic("SELinux: Unable to register AVC netcache callback\n"); diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index e9560b078efe..7a0ead4da479 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -4553,6 +4553,11 @@ struct lsm_blob_sizes smack_blob_sizes __lsm_ro_after_init = { .lbs_superblock = sizeof(struct superblock_smack), }; +static struct lsm_id smack_lsmid __lsm_ro_after_init = { + .lsm = "smack", + .slot = LSMBLOB_NEEDED +}; + static struct security_hook_list smack_hooks[] __lsm_ro_after_init = { LSM_HOOK_INIT(ptrace_access_check, smack_ptrace_access_check), LSM_HOOK_INIT(ptrace_traceme, smack_ptrace_traceme), @@ -4743,7 +4748,7 @@ static __init int smack_init(void) /* * Register with LSM */ - security_add_hooks(smack_hooks, ARRAY_SIZE(smack_hooks), "smack"); + security_add_hooks(smack_hooks, ARRAY_SIZE(smack_hooks), &smack_lsmid); smack_enabled = 1; pr_info("Smack: Initializing.\n"); diff --git a/security/tomoyo/tomoyo.c b/security/tomoyo/tomoyo.c index 716c92ec941a..f1968e80f06d 100644 --- a/security/tomoyo/tomoyo.c +++ b/security/tomoyo/tomoyo.c @@ -529,6 +529,11 @@ static void tomoyo_task_free(struct task_struct *task) } } +static struct lsm_id tomoyo_lsmid __lsm_ro_after_init = { + .lsm = "tomoyo", + .slot = LSMBLOB_NOT_NEEDED +}; + /* * tomoyo_security_ops is a "struct security_operations" which is used for * registering TOMOYO. @@ -581,7 +586,8 @@ static int __init tomoyo_init(void) struct tomoyo_task *s = tomoyo_task(current); /* register ourselves with the security framework */ - security_add_hooks(tomoyo_hooks, ARRAY_SIZE(tomoyo_hooks), "tomoyo"); + security_add_hooks(tomoyo_hooks, ARRAY_SIZE(tomoyo_hooks), + &tomoyo_lsmid); pr_info("TOMOYO Linux initialized\n"); s->domain_info = &tomoyo_kernel_domain; atomic_inc(&tomoyo_kernel_domain.users); diff --git a/security/yama/yama_lsm.c b/security/yama/yama_lsm.c index efac68556b45..0529ecc86954 100644 --- a/security/yama/yama_lsm.c +++ b/security/yama/yama_lsm.c @@ -425,6 +425,11 @@ static int yama_ptrace_traceme(struct task_struct *parent) return rc; } +static struct lsm_id yama_lsmid __lsm_ro_after_init = { + .lsm = "yama", + .slot = LSMBLOB_NOT_NEEDED +}; + static struct security_hook_list yama_hooks[] __lsm_ro_after_init = { LSM_HOOK_INIT(ptrace_access_check, yama_ptrace_access_check), LSM_HOOK_INIT(ptrace_traceme, yama_ptrace_traceme), @@ -482,7 +487,7 @@ static inline void yama_init_sysctl(void) { } static int __init yama_init(void) { pr_info("Yama: becoming mindful.\n"); - security_add_hooks(yama_hooks, ARRAY_SIZE(yama_hooks), "yama"); + security_add_hooks(yama_hooks, ARRAY_SIZE(yama_hooks), &yama_lsmid); yama_init_sysctl(); return 0; } From patchwork Thu Aug 29 23:29:12 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 11122593 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id B011914DE for ; Thu, 29 Aug 2019 23:29:47 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 83F712173E for ; Thu, 29 Aug 2019 23:29:47 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="Tqt1IBzb" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726014AbfH2X3r (ORCPT ); Thu, 29 Aug 2019 19:29:47 -0400 Received: from sonic302-28.consmr.mail.gq1.yahoo.com ([98.137.68.154]:43731 "EHLO sonic302-28.consmr.mail.gq1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726369AbfH2X3q (ORCPT ); Thu, 29 Aug 2019 19:29:46 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1567121384; bh=CbZU5iRe+yH1VCf2y2WYC0jsmwdjRjXMBNn1U3uoaKg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=Tqt1IBzbk/pLGUoVSCfzx/ORlpWR1yyaQiPBZsPxMiimt8XBAtOmbowxiDzRzWxe6JZQ84un4gtGs5WfI3t5lyC9tggva6DXYtrK2kZSX2/LiOn5zug121J42cU58jmgqUIjFawFGVmZ3eoF8lH5TCioPxjUlFbaA892BHNSn+Jlm00LEgKVn9Kyj4o/c22Qz8myG3hQ/vfuP1ZALi/cPaHLC+v+iCEVyxjqyFKu9rduEzsiTPPpw7OE4dK3CQwQN+ELPAtd69wizQXloXW22UmLbBVT2jRYXgqk+CY21hsF6CQtxn8F+xgZXUkiH0pJxHfNtztsSmpH0LUMN2LSfA== X-YMail-OSG: LebIsRwVM1nlGeAstWLDnX_6oM2.Vl9337O._Svb4NSYvdf0Bl4OqSn5E1r75aB rfD_Cpn.TF6Btdkk5J2ca7vOVUUnrQtftNVdOeOnuqqRe35b695lNmnQ4BdNd.II9OmV_bVIGXey rrAhZN7To4AyXbJ_qg2YjHMk5U647hkgdhJ2Y7sen36tw.rV7K8i0P63OoKCErwBvJbdbC3lBsX7 G2azhpWU0rRwRJcDhaxnLpZgdP83JKCNvg_LlGqZ1eS8SUCq9nDRCWhNWdf1GdE.kKsWbMdrxxGI DcMoGg6dSYHnEJ15sftipz6hKY.9wk4R6Gda5y879rRaoesdtkshQ8OXFD4N9Ua0v0AZKD6C0kDh oZL9Wpw2YnY.lplwGD8epo0d9lw5DF7GLD4POpHjbizOX_0Grg07WXJDAE4cKM2RVYBcaMPuedrM ysQcBeQ8Td.8H8E_7P9hqXLsNULpGgAt4NGBnzb.8WkK_qqll7FpZCoj5P_dzEQW83JlZR5aud05 qr0Bblwv7552D9EK_gxgac0T7EzHMHfcAV71.WUAuHBA3hFaD_XKAVMWfM6MKQgWBsVIJzHTuNFl kRFqIbCmcdpXyOwEb8L.AgYAqgAOl1c7Q7XkQW5ZErjXpw2WzK4qv0kW3m9TjfUo6_3414LBeYw7 7XG8wKRDFCSHF5.9Z7jbEuEOoCuDI309f7C1ZQLMjy7mOB7E3X80PO5XOpuu2WpKpc5aK99NJDz7 mMD4m7euO8SrXTHbfGDXRaU2DpeF6.I_AIgDF9sCijNPPkzybv2q33h.pzKqQoAzRF1XCfwlPw0. JLlaYjKQTH7JMqbjYy.np__KJ4vFdCP1hY9a4F5Rd8KhU8jQ6k0ewlSFIWHODJzw_.3Warm1nW35 GeO3itgLZFur5Hs2wuLVgslhPpqkH4WGdkRpBL3f9dArcSyM2.dV2f9aQYsGD3Za7QpfecnUbdCR FKza1CHQ20_IS3i4gJ8_KlSV5UkwAcb1_UmSq23FGXYcs6sJTO24w_93RIZNfhwazr0IBuwJPn7N Vo0J91ow8DGmZh1ecOYPgRuttscKbZ8kCKAeiosY7G4q3MUxTQpzP4ngsFpiWJNhEj3x4NgVK9G5 Z0zXCmk7ZmtefEwYeaqQ4DfarJ3pv7rJhQSvXroyIeVnfJ03UAdU37uo7V3W3ax2hHdIdyqfDC1x r3yndxYf9uT_AuDEk2gb1w6ZFstTcJ.jViSG0g5DN1Yg_.GRCvmFI6imFLMuQ2gtAz3ZKQ0Q0sUP IYC_iDPvsALxFpD5nGsMaMKxgq9CWuGszeDTS4t6MbITzhMB0hIb_3l2WKyXU2tE35.aa1xc- Received: from sonic.gate.mail.ne1.yahoo.com by sonic302.consmr.mail.gq1.yahoo.com with HTTP; Thu, 29 Aug 2019 23:29:44 +0000 Received: by smtp412.mail.gq1.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID ded9e12cc42d2f561e2af538140d1439; Thu, 29 Aug 2019 23:29:44 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, jmorris@namei.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org Cc: casey@schaufler-ca.com, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, paul@paul-moore.com, sds@tycho.nsa.gov Subject: [PATCH v8 05/28] LSM: Use lsmblob in security_audit_rule_match Date: Thu, 29 Aug 2019 16:29:12 -0700 Message-Id: <20190829232935.7099-6-casey@schaufler-ca.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190829232935.7099-1-casey@schaufler-ca.com> References: <20190829232935.7099-1-casey@schaufler-ca.com> MIME-Version: 1.0 Sender: selinux-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: selinux@vger.kernel.org Change the secid parameter of security_audit_rule_match to a lsmblob structure pointer. Pass the entry from the lsmblob structure for the approprite slot to the LSM hook. Change the users of security_audit_rule_match to use the lsmblob instead of a u32. In some cases this requires a temporary conversion using lsmblob_init() that will go away when other interfaces get converted. Reviewed-by: Kees Cook Reviewed-by: John Johansen Signed-off-by: Casey Schaufler --- include/linux/security.h | 7 ++++--- kernel/auditfilter.c | 7 +++++-- kernel/auditsc.c | 14 ++++++++++---- security/integrity/ima/ima.h | 4 ++-- security/integrity/ima/ima_policy.c | 7 +++++-- security/security.c | 18 +++++++++++++++--- 6 files changed, 41 insertions(+), 16 deletions(-) diff --git a/include/linux/security.h b/include/linux/security.h index 5bb8b9a6fa84..4f8b478bc3a1 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -1761,7 +1761,8 @@ static inline int security_key_getsecurity(struct key *key, char **_buffer) #ifdef CONFIG_SECURITY int security_audit_rule_init(u32 field, u32 op, char *rulestr, void **lsmrule); int security_audit_rule_known(struct audit_krule *krule); -int security_audit_rule_match(u32 secid, u32 field, u32 op, void *lsmrule); +int security_audit_rule_match(struct lsmblob *blob, u32 field, u32 op, + void *lsmrule); void security_audit_rule_free(void *lsmrule); #else @@ -1777,8 +1778,8 @@ static inline int security_audit_rule_known(struct audit_krule *krule) return 0; } -static inline int security_audit_rule_match(u32 secid, u32 field, u32 op, - void *lsmrule) +static inline int security_audit_rule_match(struct lsmblob *blob, u32 field, + u32 op, void *lsmrule) { return 0; } diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c index 63f8b3f26fab..8786b95b60bd 100644 --- a/kernel/auditfilter.c +++ b/kernel/auditfilter.c @@ -1324,6 +1324,7 @@ int audit_filter(int msgtype, unsigned int listtype) struct audit_field *f = &e->rule.fields[i]; pid_t pid; u32 sid; + struct lsmblob blob; switch (f->type) { case AUDIT_PID: @@ -1354,8 +1355,10 @@ int audit_filter(int msgtype, unsigned int listtype) case AUDIT_SUBJ_CLR: if (f->lsm_rule) { security_task_getsecid(current, &sid); - result = security_audit_rule_match(sid, - f->type, f->op, f->lsm_rule); + lsmblob_init(&blob, sid); + result = security_audit_rule_match( + &blob, f->type, + f->op, f->lsm_rule); } break; case AUDIT_EXE: diff --git a/kernel/auditsc.c b/kernel/auditsc.c index d1eab1d4a930..18ee5556c086 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -445,6 +445,7 @@ static int audit_filter_rules(struct task_struct *tsk, const struct cred *cred; int i, need_sid = 1; u32 sid; + struct lsmblob blob; unsigned int sessionid; cred = rcu_dereference_check(tsk->cred, tsk == current || task_creation); @@ -630,7 +631,9 @@ static int audit_filter_rules(struct task_struct *tsk, security_task_getsecid(tsk, &sid); need_sid = 0; } - result = security_audit_rule_match(sid, f->type, + lsmblob_init(&blob, sid); + result = security_audit_rule_match(&blob, + f->type, f->op, f->lsm_rule); } @@ -645,15 +648,17 @@ static int audit_filter_rules(struct task_struct *tsk, if (f->lsm_rule) { /* Find files that match */ if (name) { + lsmblob_init(&blob, name->osid); result = security_audit_rule_match( - name->osid, + &blob, f->type, f->op, f->lsm_rule); } else if (ctx) { list_for_each_entry(n, &ctx->names_list, list) { + lsmblob_init(&blob, n->osid); if (security_audit_rule_match( - n->osid, + &blob, f->type, f->op, f->lsm_rule)) { @@ -665,7 +670,8 @@ static int audit_filter_rules(struct task_struct *tsk, /* Find ipc objects that match */ if (!ctx || ctx->type != AUDIT_IPC) break; - if (security_audit_rule_match(ctx->ipc.osid, + lsmblob_init(&blob, ctx->ipc.osid); + if (security_audit_rule_match(&blob, f->type, f->op, f->lsm_rule)) ++result; diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h index d213e835c498..5a337239d9e4 100644 --- a/security/integrity/ima/ima.h +++ b/security/integrity/ima/ima.h @@ -307,8 +307,8 @@ static inline int security_filter_rule_init(u32 field, u32 op, char *rulestr, return -EINVAL; } -static inline int security_filter_rule_match(u32 secid, u32 field, u32 op, - void *lsmrule) +static inline int security_filter_rule_match(struct lsmblob *blob, u32 field, + u32 op, void *lsmrule) { return -EINVAL; } diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c index e0cc323f948f..e7b8ce942950 100644 --- a/security/integrity/ima/ima_policy.c +++ b/security/integrity/ima/ima_policy.c @@ -327,6 +327,7 @@ static bool ima_match_rules(struct ima_rule_entry *rule, struct inode *inode, for (i = 0; i < MAX_LSM_RULES; i++) { int rc = 0; u32 osid; + struct lsmblob blob; int retried = 0; if (!rule->lsm[i].rule) @@ -337,7 +338,8 @@ static bool ima_match_rules(struct ima_rule_entry *rule, struct inode *inode, case LSM_OBJ_ROLE: case LSM_OBJ_TYPE: security_inode_getsecid(inode, &osid); - rc = security_filter_rule_match(osid, + lsmblob_init(&blob, osid); + rc = security_filter_rule_match(&blob, rule->lsm[i].type, Audit_equal, rule->lsm[i].rule); @@ -345,7 +347,8 @@ static bool ima_match_rules(struct ima_rule_entry *rule, struct inode *inode, case LSM_SUBJ_USER: case LSM_SUBJ_ROLE: case LSM_SUBJ_TYPE: - rc = security_filter_rule_match(secid, + lsmblob_init(&blob, secid); + rc = security_filter_rule_match(&blob, rule->lsm[i].type, Audit_equal, rule->lsm[i].rule); diff --git a/security/security.c b/security/security.c index 27e2db3d6b04..fa6e425e6f29 100644 --- a/security/security.c +++ b/security/security.c @@ -424,7 +424,7 @@ static int lsm_append(const char *new, char **result) /* * Current index to use while initializing the lsmblob secid list. */ -static int lsm_slot __initdata; +static int lsm_slot __lsm_ro_after_init; /** * security_add_hooks - Add a modules hooks to the hook lists. @@ -2433,9 +2433,21 @@ void security_audit_rule_free(void *lsmrule) call_void_hook(audit_rule_free, lsmrule); } -int security_audit_rule_match(u32 secid, u32 field, u32 op, void *lsmrule) +int security_audit_rule_match(struct lsmblob *blob, u32 field, u32 op, + void *lsmrule) { - return call_int_hook(audit_rule_match, 0, secid, field, op, lsmrule); + struct security_hook_list *hp; + int rc; + + hlist_for_each_entry(hp, &security_hook_heads.audit_rule_match, list) { + if (WARN_ON(hp->lsmid->slot < 0 || hp->lsmid->slot >= lsm_slot)) + continue; + rc = hp->hook.audit_rule_match(blob->secid[hp->lsmid->slot], + field, op, lsmrule); + if (rc != 0) + return rc; + } + return 0; } #endif /* CONFIG_AUDIT */ From patchwork Thu Aug 29 23:29:13 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 11122611 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 01ABE1395 for ; Thu, 29 Aug 2019 23:29:52 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id D3F5421874 for ; Thu, 29 Aug 2019 23:29:51 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="VC87Umaz" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727307AbfH2X3v (ORCPT ); Thu, 29 Aug 2019 19:29:51 -0400 Received: from sonic302-28.consmr.mail.gq1.yahoo.com ([98.137.68.154]:45815 "EHLO sonic302-28.consmr.mail.gq1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727522AbfH2X3u (ORCPT ); Thu, 29 Aug 2019 19:29:50 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1567121389; bh=pBDl/1vQPZOTGhA3y1ZBLm/3xBXXHuqBGnmdEc2nJIk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=VC87UmazrUBVMSm2Vmz/vC38xd4Ws3sPO9/QuEEZ2jJIOeUhaMSmIFDtkoZJRDuInPRJ2f8MwGGKsvA3cpahPYDyLMW1TOfTiiDKFNa9W1HK6017EQ4adGx91w9xOZ4aJqcSt81RQ5MSIEBGl1KgLD28uHwnBvV7qBIBE10p0+mkBQ4qh5U3Fl+2QIxhIFaPeR3+y7UpXCdEG2TR4Qtyf7+WmAQzktb6ukbYxx/jO8K3YLT46ld31jE2SLsG3czVkC7gCokIKhHRTRESIqBpB7RbxfQMfaomPS4nAQoUeKol1TxfjJ3xt8bd8Kf4ZYmB5IVvng1YadJtYHVk7Tl4lQ== X-YMail-OSG: d1li1tIVM1lYiojYCV00XIT2qJomg8n9N6WiWjGtfYBZHPq62KMMZb4gI9F_L1O .umAnpNqphLzA_zhIy7RQL3qouG3TFPUKbCqL.DxnJM6GUetezXPKM53lfvDb4fd_Z6L8v1D2.Wn lQmws.mUkf6DRfD2iQ9sD6LcSmBu0fJ2rBXmJY3D7_YfYN2MbcgzX90IfF.bYpnPj0dLPiiYGCGX MseO3._PFIp8pIPWnTqd3YR_TZBTmSWAyF4H.vy8D5hQgeLyhiWHaup0tMfzP243ySPC5.VI92Kb FZEAZWS0PpjgPXuR26kaCfRQMub_U46R8RIIwNYGkn6C9BqPO6hUg0eFaAMMST6RwUMrVVJejy_1 dxlX_nI0r47FuqifXYf7A97ffG9Wh8gWN9Kbf_6LPnW3idO47pr6Br_LpklYoXPOVk12f4W96PTE h0f5CQ.M6jyK18jC6RdxZW8w8cIUMIfpgeNeSq_amoQvqGdyfdzloX3joqD.aek2pWLoww.5o7Hi zEKt1zWi6jsOjKoGJmMtIcNgPZ3rUEmbNtG9G3BksgHy0S5Mp6G5oL2aKr9nyPmHQ5DM5UjgTOi9 cORRI9gviwEIosZH0hQ.6zn5iszjUY.PFUOHGgFzg1X13N8wqxVItpGoMCi3M7sTGvqjj7Uhrp2. O8Q7PFd0H1Paf.gBdNJOXqEW8tcI1KLo9ldYgkeRevwUfkh9pF2itW_ec.dCtUJ9QP6n4Ywd1V3v dSbjDoBZFAxm1ZMR2RAyr7m00p61KVveRpQWuugDoPKbHKg2.dHvA3.9LCmHEp5nOrviir1lTKlz AJoJRmbqEKjGlZYQldIS4KYQEh97k4vs.wx7becEKJELpKce9lRKsvMNLrDBSiSh8uLv1ck03ovP FoVYoe5eg.K679krV84thIreSpSbhPRopbG7530BC2UORD6kH5yB9EsrRmqGcynQE6hosw9RF_XL 7zB4VOF8X_jKiPJ87A4JbaOxcePCs6OVKco30A2EKOZ_HNfGodeOnSD5OmusU0X3XMDt14EDbtos vTHNn7Vqi0I9UhQjN1Y_I6wYmjncF6INReQZolMQT4Cn5zOrvJMdJ5kZ1Le74StHUrB7dBcRGGq6 6TV2nfEfrIVdENim9SZVgZke3Nu2OS.JJecXCAUF9H4bhBjee2FHvogZh8907FgOAMcRykWZb8_s yWBY2VG3EPHJaL7Vzu7Gnw.DUgG7sgpnVZjjLcIokp7zmpOp201Rl9pC1OImGTGZ3RqiW.GyYuBn 00Z1mTCbisgdihPmmmweCMaobS36g15ozsF0TW2HLWby9bHjYSWz9QasCFJXGGkFyZ.0J2AsaL9G niD0Qzco- Received: from sonic.gate.mail.ne1.yahoo.com by sonic302.consmr.mail.gq1.yahoo.com with HTTP; Thu, 29 Aug 2019 23:29:49 +0000 Received: by smtp412.mail.gq1.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID ded9e12cc42d2f561e2af538140d1439; Thu, 29 Aug 2019 23:29:44 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, jmorris@namei.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org Cc: casey@schaufler-ca.com, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, paul@paul-moore.com, sds@tycho.nsa.gov Subject: [PATCH v8 06/28] LSM: Use lsmblob in security_kernel_act_as Date: Thu, 29 Aug 2019 16:29:13 -0700 Message-Id: <20190829232935.7099-7-casey@schaufler-ca.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190829232935.7099-1-casey@schaufler-ca.com> References: <20190829232935.7099-1-casey@schaufler-ca.com> MIME-Version: 1.0 Sender: selinux-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: selinux@vger.kernel.org Change the security_kernel_act_as interface to use a lsmblob structure in place of the single u32 secid in support of module stacking. Change it's only caller, set_security_override, to do the same. Change that one's only caller, set_security_override_from_ctx, to call it with the new parameter type. Reviewed-by: Kees Cook Reviewed-by: John Johansen Signed-off-by: Casey Schaufler --- include/linux/cred.h | 3 ++- include/linux/security.h | 5 +++-- kernel/cred.c | 10 ++++++---- security/security.c | 14 ++++++++++++-- 4 files changed, 23 insertions(+), 9 deletions(-) diff --git a/include/linux/cred.h b/include/linux/cred.h index efb6edf32de7..9a21c376ed97 100644 --- a/include/linux/cred.h +++ b/include/linux/cred.h @@ -22,6 +22,7 @@ struct cred; struct inode; +struct lsmblob; /* * COW Supplementary groups list @@ -165,7 +166,7 @@ extern const struct cred *override_creds(const struct cred *); extern void revert_creds(const struct cred *); extern struct cred *prepare_kernel_cred(struct task_struct *); extern int change_create_files_as(struct cred *, struct inode *); -extern int set_security_override(struct cred *, u32); +extern int set_security_override(struct cred *, struct lsmblob *); extern int set_security_override_from_ctx(struct cred *, const char *); extern int set_create_files_as(struct cred *, struct inode *); extern int cred_fscmp(const struct cred *, const struct cred *); diff --git a/include/linux/security.h b/include/linux/security.h index 4f8b478bc3a1..313e45a3cac3 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -388,7 +388,7 @@ void security_cred_free(struct cred *cred); int security_prepare_creds(struct cred *new, const struct cred *old, gfp_t gfp); void security_transfer_creds(struct cred *new, const struct cred *old); void security_cred_getsecid(const struct cred *c, u32 *secid); -int security_kernel_act_as(struct cred *new, u32 secid); +int security_kernel_act_as(struct cred *new, struct lsmblob *blob); int security_kernel_create_files_as(struct cred *new, struct inode *inode); int security_kernel_module_request(char *kmod_name); int security_kernel_load_data(enum kernel_load_data_id id); @@ -971,7 +971,8 @@ static inline void security_transfer_creds(struct cred *new, { } -static inline int security_kernel_act_as(struct cred *cred, u32 secid) +static inline int security_kernel_act_as(struct cred *cred, + struct lsmblob *blob) { return 0; } diff --git a/kernel/cred.c b/kernel/cred.c index 45d77284aed0..71c14dda107e 100644 --- a/kernel/cred.c +++ b/kernel/cred.c @@ -701,14 +701,14 @@ EXPORT_SYMBOL(prepare_kernel_cred); /** * set_security_override - Set the security ID in a set of credentials * @new: The credentials to alter - * @secid: The LSM security ID to set + * @blob: The LSM security information to set * * Set the LSM security ID in a set of credentials so that the subjective * security is overridden when an alternative set of credentials is used. */ -int set_security_override(struct cred *new, u32 secid) +int set_security_override(struct cred *new, struct lsmblob *blob) { - return security_kernel_act_as(new, secid); + return security_kernel_act_as(new, blob); } EXPORT_SYMBOL(set_security_override); @@ -724,6 +724,7 @@ EXPORT_SYMBOL(set_security_override); */ int set_security_override_from_ctx(struct cred *new, const char *secctx) { + struct lsmblob blob; u32 secid; int ret; @@ -731,7 +732,8 @@ int set_security_override_from_ctx(struct cred *new, const char *secctx) if (ret < 0) return ret; - return set_security_override(new, secid); + lsmblob_init(&blob, secid); + return set_security_override(new, &blob); } EXPORT_SYMBOL(set_security_override_from_ctx); diff --git a/security/security.c b/security/security.c index fa6e425e6f29..fa7ab1334f22 100644 --- a/security/security.c +++ b/security/security.c @@ -1627,9 +1627,19 @@ void security_cred_getsecid(const struct cred *c, u32 *secid) } EXPORT_SYMBOL(security_cred_getsecid); -int security_kernel_act_as(struct cred *new, u32 secid) +int security_kernel_act_as(struct cred *new, struct lsmblob *blob) { - return call_int_hook(kernel_act_as, 0, new, secid); + struct security_hook_list *hp; + int rc; + + hlist_for_each_entry(hp, &security_hook_heads.kernel_act_as, list) { + if (WARN_ON(hp->lsmid->slot < 0 || hp->lsmid->slot >= lsm_slot)) + continue; + rc = hp->hook.kernel_act_as(new, blob->secid[hp->lsmid->slot]); + if (rc != 0) + return rc; + } + return 0; } int security_kernel_create_files_as(struct cred *new, struct inode *inode) From patchwork Thu Aug 29 23:29:14 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 11122607 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 885C814DE for ; Thu, 29 Aug 2019 23:29:50 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 5D23321874 for ; Thu, 29 Aug 2019 23:29:50 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="HhDvHQQc" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1725847AbfH2X3t (ORCPT ); Thu, 29 Aug 2019 19:29:49 -0400 Received: from sonic310-28.consmr.mail.gq1.yahoo.com ([98.137.69.154]:44051 "EHLO sonic310-28.consmr.mail.gq1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727059AbfH2X3t (ORCPT ); Thu, 29 Aug 2019 19:29:49 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1567121388; bh=Ka1Gx+I96hAzkKoAYSBNjQ1iDMrTZlQNs08b4b4eI/w=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=HhDvHQQckZhtaWCZfkK0X2+KMxc8/sBoJpqxsWEdZopL1lTuaB7ebbi0/5cj5LMz4oOhBkJSX3P8XNffc79liAKv69dcBZDQN5kMrM6OdGZhwIJppr6wMcsce+q+urvQOmfoIV/WEcFzGfhue8xYrQMbBRaUTID4CXjZFpMDE/B1aUa2CyzNwvCM2PHwc/nEf10wt7REEe6UILciZjKstI/pZvqAd1/Lby0hOVRL5Sd8luX7j2F7XSSwNf9L637L54g0qxetrnkvdllpitHi58U6sSDSklSE1BoOTcMksAp8f/s3yhbK4fHWMEaz0ONLbhaodYPs7bP+LJdUavXC2Q== X-YMail-OSG: v5MuQD8VM1m8Fcynagn_RlVnMKrPbJjCHjxg6myIwGOd9sHXzg1a67sp2LwrMzT ec9RHghsREgodCn5ROuGV0QFyZuZUnlF.G75KyIKEgfCDtbAJUjqZdkjZ9HRoOgV34kPpdw2cNNL S8RPgnX4uczK3SAc2NJ0uZxyVX0FtugDKeeQxgZGEzJc0LoPLBsONVPyeF9OBcUzWG2sNJy_URsR L1yKcx3jdRr5fki9vVoNPOa_rqyZJ5ap8bU.S7hMvjt0BZty1fT_B8GZ.QejPTbf043DkEyyjZdu qz53G_NXMMn.51VrvL9qtRq95ZFu5U.HmY9r6R2Ct5YE.L4_iRXisX7HTGydr82Wkkt9WTd95jKN 9w9BlBTYTNVBeu1hNxCripJu1kUZiaM43Tk16joRo0JD9COJENubHCLtS9BGwf3eYnbK3OUwkT1N ipK4WqoUzYTXUJkBNJqoKzSI4XGK55STy1SGaB5mGGfCWga2KO21I9rRMlo2nEnx.S..U1EBnT5h .NesF_BpcfW8yJx73JXoHUJxpsVasX_5A8sB46cXG22mMYSW0i1V3GL53Ns_FDH8t0KU.ibxj7iq 6p0vrKSdFbguYH5bcgWRH.DwZzDR.w6Lau7akoqZE6zBc5nNSCGDmheCMy93lDuFH64uDFLeXhYJ Ez1wC7hVCBtsuRdH764qEsCCVSouum5ilNiVOeLrOJyAIoxI2zwA46wmiCZVcWQUR62BTSlaSx7s lguDakzr9DaA16cm6hCY1wtTn.218FRFniI7AqdJXKqG0loEYjawdvU4m5JHsQj1ocXBOiPnVZTd KOkTd2Dn7tKsNSp_2yBK4Jxqk0fm3SRd.tsOPmtqtpDjJSZhDFBw_hmBxp9s.g3RI9nZqagYjRvR ILRAdjpQhSyOfJpieE1Sv8hQub7erP3C1S5z5vpSi7b_qzMgXzUdYFavRbXf2_obUqqqIE8Zi6mx K2dUtwzSkYpSx5j39hJs3xjH7CxicqJ181jdweOMMhPWBxlRboxJiLk0EAguMmRdUakhEY9EFizs 6oYDlrqDVlfcCZYHUvRkmcHdnO_d_vcO.qH.3unUmMEvUvZenJbqoBjFbCSnfb78I8coYS4LJuAu uwf5MpO.NAHGCG1CRbOnodWATo.c.Dh9BZ.JYPtV8fiEeGzfjebswk3d_Xq0z4jrilopUPoq9.4h oFPxhseQ2uOKLLqqZoapHPcWva3uQANQwGgOK2MB6OSZ3dcCv19etjxPndmwS4idTE2hpPksRjxg xs1VY_jEuzW8n1foAWhkxD4DnYza7jhupz1qT6n5V2exNx5JjU3iCjFA8MHymbmyWmqLT3wpaLRa 4VsFm23NV Received: from sonic.gate.mail.ne1.yahoo.com by sonic310.consmr.mail.gq1.yahoo.com with HTTP; Thu, 29 Aug 2019 23:29:48 +0000 Received: by smtp412.mail.gq1.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID ded9e12cc42d2f561e2af538140d1439; Thu, 29 Aug 2019 23:29:45 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, jmorris@namei.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org Cc: casey@schaufler-ca.com, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, paul@paul-moore.com, sds@tycho.nsa.gov Subject: [PATCH v8 07/28] net: Prepare UDS for security module stacking Date: Thu, 29 Aug 2019 16:29:14 -0700 Message-Id: <20190829232935.7099-8-casey@schaufler-ca.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190829232935.7099-1-casey@schaufler-ca.com> References: <20190829232935.7099-1-casey@schaufler-ca.com> MIME-Version: 1.0 Sender: selinux-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: selinux@vger.kernel.org Change the data used in UDS SO_PEERSEC processing from a secid to a more general struct lsmblob. Update the security_socket_getpeersec_dgram() interface to use the lsmblob. There is a small amount of scaffolding code that will come out when the security_secid_to_secctx() code is brought in line with the lsmblob. Reviewed-by: Kees Cook Reviewed-by: John Johansen Signed-off-by: Casey Schaufler --- include/linux/security.h | 7 +++++-- include/net/af_unix.h | 2 +- include/net/scm.h | 8 +++++--- net/ipv4/ip_sockglue.c | 8 +++++--- net/unix/af_unix.c | 6 +++--- security/security.c | 18 +++++++++++++++--- 6 files changed, 34 insertions(+), 15 deletions(-) diff --git a/include/linux/security.h b/include/linux/security.h index 313e45a3cac3..dcf20da87d1b 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -1280,7 +1280,8 @@ int security_socket_shutdown(struct socket *sock, int how); int security_sock_rcv_skb(struct sock *sk, struct sk_buff *skb); int security_socket_getpeersec_stream(struct socket *sock, char __user *optval, int __user *optlen, unsigned len); -int security_socket_getpeersec_dgram(struct socket *sock, struct sk_buff *skb, u32 *secid); +int security_socket_getpeersec_dgram(struct socket *sock, struct sk_buff *skb, + struct lsmblob *blob); int security_sk_alloc(struct sock *sk, int family, gfp_t priority); void security_sk_free(struct sock *sk); void security_sk_clone(const struct sock *sk, struct sock *newsk); @@ -1418,7 +1419,9 @@ static inline int security_socket_getpeersec_stream(struct socket *sock, char __ return -ENOPROTOOPT; } -static inline int security_socket_getpeersec_dgram(struct socket *sock, struct sk_buff *skb, u32 *secid) +static inline int security_socket_getpeersec_dgram(struct socket *sock, + struct sk_buff *skb, + struct lsmblob *blob) { return -ENOPROTOOPT; } diff --git a/include/net/af_unix.h b/include/net/af_unix.h index 3426d6dacc45..933492c08b8c 100644 --- a/include/net/af_unix.h +++ b/include/net/af_unix.h @@ -36,7 +36,7 @@ struct unix_skb_parms { kgid_t gid; struct scm_fp_list *fp; /* Passed files */ #ifdef CONFIG_SECURITY_NETWORK - u32 secid; /* Security ID */ + struct lsmblob lsmblob; /* Security LSM data */ #endif u32 consumed; } __randomize_layout; diff --git a/include/net/scm.h b/include/net/scm.h index 1ce365f4c256..e2e71c4bf9d0 100644 --- a/include/net/scm.h +++ b/include/net/scm.h @@ -33,7 +33,7 @@ struct scm_cookie { struct scm_fp_list *fp; /* Passed files */ struct scm_creds creds; /* Skb credentials */ #ifdef CONFIG_SECURITY_NETWORK - u32 secid; /* Passed security ID */ + struct lsmblob lsmblob; /* Passed LSM data */ #endif }; @@ -46,7 +46,7 @@ struct scm_fp_list *scm_fp_dup(struct scm_fp_list *fpl); #ifdef CONFIG_SECURITY_NETWORK static __inline__ void unix_get_peersec_dgram(struct socket *sock, struct scm_cookie *scm) { - security_socket_getpeersec_dgram(sock, NULL, &scm->secid); + security_socket_getpeersec_dgram(sock, NULL, &scm->lsmblob); } #else static __inline__ void unix_get_peersec_dgram(struct socket *sock, struct scm_cookie *scm) @@ -97,7 +97,9 @@ static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct sc int err; if (test_bit(SOCK_PASSSEC, &sock->flags)) { - err = security_secid_to_secctx(scm->secid, &secdata, &seclen); + /* Scaffolding - it has to be element 0 for now */ + err = security_secid_to_secctx(scm->lsmblob.secid[0], + &secdata, &seclen); if (!err) { put_cmsg(msg, SOL_SOCKET, SCM_SECURITY, seclen, secdata); diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c index 82f341e84fae..2a5c868ce135 100644 --- a/net/ipv4/ip_sockglue.c +++ b/net/ipv4/ip_sockglue.c @@ -130,15 +130,17 @@ static void ip_cmsg_recv_checksum(struct msghdr *msg, struct sk_buff *skb, static void ip_cmsg_recv_security(struct msghdr *msg, struct sk_buff *skb) { + struct lsmblob lb; char *secdata; - u32 seclen, secid; + u32 seclen; int err; - err = security_socket_getpeersec_dgram(NULL, skb, &secid); + err = security_socket_getpeersec_dgram(NULL, skb, &lb); if (err) return; - err = security_secid_to_secctx(secid, &secdata, &seclen); + /* Scaffolding - it has to be element 0 */ + err = security_secid_to_secctx(lb.secid[0], &secdata, &seclen); if (err) return; diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index ddb838a1b74c..c50a004a1389 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -143,17 +143,17 @@ static struct hlist_head *unix_sockets_unbound(void *addr) #ifdef CONFIG_SECURITY_NETWORK static void unix_get_secdata(struct scm_cookie *scm, struct sk_buff *skb) { - UNIXCB(skb).secid = scm->secid; + UNIXCB(skb).lsmblob = scm->lsmblob; } static inline void unix_set_secdata(struct scm_cookie *scm, struct sk_buff *skb) { - scm->secid = UNIXCB(skb).secid; + scm->lsmblob = UNIXCB(skb).lsmblob; } static inline bool unix_secdata_eq(struct scm_cookie *scm, struct sk_buff *skb) { - return (scm->secid == UNIXCB(skb).secid); + return lsmblob_equal(&scm->lsmblob, &(UNIXCB(skb).lsmblob)); } #else static inline void unix_get_secdata(struct scm_cookie *scm, struct sk_buff *skb) diff --git a/security/security.c b/security/security.c index fa7ab1334f22..fe76dfa0f2fd 100644 --- a/security/security.c +++ b/security/security.c @@ -2120,10 +2120,22 @@ int security_socket_getpeersec_stream(struct socket *sock, char __user *optval, optval, optlen, len); } -int security_socket_getpeersec_dgram(struct socket *sock, struct sk_buff *skb, u32 *secid) +int security_socket_getpeersec_dgram(struct socket *sock, struct sk_buff *skb, + struct lsmblob *blob) { - return call_int_hook(socket_getpeersec_dgram, -ENOPROTOOPT, sock, - skb, secid); + struct security_hook_list *hp; + int rc = -ENOPROTOOPT; + + hlist_for_each_entry(hp, &security_hook_heads.socket_getpeersec_dgram, + list) { + if (WARN_ON(hp->lsmid->slot < 0 || hp->lsmid->slot >= lsm_slot)) + continue; + rc = hp->hook.socket_getpeersec_dgram(sock, skb, + &blob->secid[hp->lsmid->slot]); + if (rc != 0) + break; + } + return rc; } EXPORT_SYMBOL(security_socket_getpeersec_dgram); From patchwork Thu Aug 29 23:29:15 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 11122601 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 3C3B71395 for ; Thu, 29 Aug 2019 23:29:49 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 1120A21874 for ; Thu, 29 Aug 2019 23:29:49 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="rLnF65pr" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727348AbfH2X3s (ORCPT ); Thu, 29 Aug 2019 19:29:48 -0400 Received: from sonic312-30.consmr.mail.gq1.yahoo.com ([98.137.69.211]:37616 "EHLO sonic312-30.consmr.mail.gq1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725848AbfH2X3s (ORCPT ); Thu, 29 Aug 2019 19:29:48 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1567121387; bh=jeAwtj61x3mTeiR+JjReHIO7CbjGJFrxN2vWv0bqU0U=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=rLnF65prC5+rOuJo1RNiWKtICQmbH1dgsyw9n0s28mHBM2iU9KB1CIpKJWmhHtrxWKOOa3bUEvnafeRAmjoGl2wqu9waC2H6eSg17lHQkL1D1VEmVoS4QfM8H7XgSOxnP9Lxnx/faECTHfZiKAJn9Xqz+MQ/nY1rwvw7tmZXy/j64zMEvt+4kZIbs5n6UuY65F/iFUQvlGnpDBQIzxaDkbUYGbHcInggg+dkdrnuLiSb6Wt+DvJkKSUHZfmEaktJU44FgV1Q/tQdAKmDrRZkc6gIN+12+he4OQL6wtbmsa59c/DqSMs+BMNYl8VCeIPePsK4WDc99LxJSlsK0K4q4w== X-YMail-OSG: _9zE_pMVM1lW9024D7DkPbExPSOJvmO0M45eb1U3k8WErKu_KIpLTNxmt0K3rVg mUu5cNz.5c_OcgJ36MUtTYoUQtjzi3CTm5ijGoTYr1WdhlW4ynPRslYBAkEdbmAwcuaJGfhNJmkg 4WG.jP4X.E3HWi1SxN.iDHO3I9Cmj4O6MSQ0M70IBno08ztQ0rsI1Uze_AYIl_eOLkQDfiQPzBwF D3N_vYD9DP1ppWN032t_86_ji75uX8k4Seg9ByC.WL5DnPHlZoPZhLA8Ra7WCWxX2T_GDrAMno.Z N7gwyBNTFnv5cAC1vHkmAv_QOreST7zneFLabh5lxUYoB9iRuBeZtSqjpeeXoZELLHogOlw2Q13w Ytkyb_IAGyDbk97CGrISP6jaG7U_3zLeHsxQI7PMh5bXuzmRS8GlQkN0QnxxysBSUzqoCNDg9PF1 6ASn8j6lf3XAh3uv12Y5Bad60McTSojPy7jDn5SZ.MvTpIJM4KEQ2l.J5fjvgaZ9FWpZUsKPH2gH Dpbo4YmswnhV2HD_fRS4b.xfzxq0DpyGVlhrhFmyAGLorZcScSFffdSNz0x0nvcrWdJU2NPD96A9 OsyuvC0fHow_GDkxNHi2TtVhgcuA_NvrCcAgvjd3xNy7pUXVRl9wyEIveZrupFmMCkEDi4L0AcWS bk4p7Aqe6KHGqMJ2qOyPUncxuF1RGYSxWT5MuZEzZPjnx8oslwjNMm9FJ2QvO7ijVHsCFmRqU.DK O1PQK9R53PAmnOxa1_M.oL.3x9hQWNneyces_dNzBNQ3924Z7PPhSQcfW_gPwrLLaRCanAQSs_.g TbPj23_8bK.HJ.hZGRcISoXirPMNTOgE1dsuoiTcvEM8WEDliDn107uPyUWVMJadg4VTdZ776o.Z oLniIiwaDJhtB9OLpbHeYEAtLcnvidcWwW1XNM80DzgwZU08xAQ6Cw5Hw0E4x.RS5uC8EcT_efPV 2kF6eWEmXtMXdRprNMb0h0xZMty0BGu0GUJXZ.QhX2Fguw2OQZMcLuDsDfmK20T_2C4vOx18tlly xZVUPcjPwEo79HIlGgfTdVzzF0JZ9tjREueRfazcJ5wCMlOj0h42XZ6g6dOxTQz9Fw7WpqbroXFp cYZ5YzTw0CKG5F2o8K8QqjCMWjhAA2srcj0uA0r1QGiDvSWFnL0B4r9DMuIg8YK9S9TprEjHWE_z Z14HkgFkxI9PCYpAHw7o3w1qaFxZNb8TGw2YOYHrUbBm8yrQkUdIfafMOecod0GcTuOUvndmTX02 qR9J1kczEQ4K4wPl9uVY7Ln9pqu6UApJm0FVEiC.d0KWSnJ7CFLrJZSbyX9imCx2mvNIc68t4wY. cUV0BbroI Received: from sonic.gate.mail.ne1.yahoo.com by sonic312.consmr.mail.gq1.yahoo.com with HTTP; Thu, 29 Aug 2019 23:29:47 +0000 Received: by smtp412.mail.gq1.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID ded9e12cc42d2f561e2af538140d1439; Thu, 29 Aug 2019 23:29:46 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, jmorris@namei.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org Cc: casey@schaufler-ca.com, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, paul@paul-moore.com, sds@tycho.nsa.gov Subject: [PATCH v8 08/28] LSM: Use lsmblob in security_secctx_to_secid Date: Thu, 29 Aug 2019 16:29:15 -0700 Message-Id: <20190829232935.7099-9-casey@schaufler-ca.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190829232935.7099-1-casey@schaufler-ca.com> References: <20190829232935.7099-1-casey@schaufler-ca.com> MIME-Version: 1.0 Sender: selinux-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: selinux@vger.kernel.org Change security_secctx_to_secid() to fill in a lsmblob instead of a u32 secid. Multiple LSMs may be able to interpret the string, and this allows for setting whichever secid is appropriate. In some cases there is scaffolding where other interfaces have yet to be converted. Reviewed-by: Kees Cook Reviewed-by: John Johansen Signed-off-by: Casey Schaufler --- include/linux/security.h | 5 +++-- kernel/cred.c | 4 +--- net/netfilter/nft_meta.c | 13 ++++++------- net/netfilter/xt_SECMARK.c | 5 ++++- net/netlabel/netlabel_unlabeled.c | 14 ++++++++------ security/security.c | 18 +++++++++++++++--- 6 files changed, 37 insertions(+), 22 deletions(-) diff --git a/include/linux/security.h b/include/linux/security.h index dcf20da87d1b..30337f1a9056 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -447,7 +447,8 @@ int security_setprocattr(const char *lsm, const char *name, void *value, int security_netlink_send(struct sock *sk, struct sk_buff *skb); int security_ismaclabel(const char *name); int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen); -int security_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid); +int security_secctx_to_secid(const char *secdata, u32 seclen, + struct lsmblob *blob); void security_release_secctx(char *secdata, u32 seclen); void security_inode_invalidate_secctx(struct inode *inode); @@ -1230,7 +1231,7 @@ static inline int security_secid_to_secctx(u32 secid, char **secdata, u32 *secle static inline int security_secctx_to_secid(const char *secdata, u32 seclen, - u32 *secid) + struct lsmblob *blob) { return -EOPNOTSUPP; } diff --git a/kernel/cred.c b/kernel/cred.c index 71c14dda107e..d70a2c02ced4 100644 --- a/kernel/cred.c +++ b/kernel/cred.c @@ -725,14 +725,12 @@ EXPORT_SYMBOL(set_security_override); int set_security_override_from_ctx(struct cred *new, const char *secctx) { struct lsmblob blob; - u32 secid; int ret; - ret = security_secctx_to_secid(secctx, strlen(secctx), &secid); + ret = security_secctx_to_secid(secctx, strlen(secctx), &blob); if (ret < 0) return ret; - lsmblob_init(&blob, secid); return set_security_override(new, &blob); } EXPORT_SYMBOL(set_security_override_from_ctx); diff --git a/net/netfilter/nft_meta.c b/net/netfilter/nft_meta.c index 987d2d6ce624..054fb4b48d51 100644 --- a/net/netfilter/nft_meta.c +++ b/net/netfilter/nft_meta.c @@ -576,21 +576,20 @@ static const struct nla_policy nft_secmark_policy[NFTA_SECMARK_MAX + 1] = { static int nft_secmark_compute_secid(struct nft_secmark *priv) { - u32 tmp_secid = 0; + struct lsmblob blob; int err; - err = security_secctx_to_secid(priv->ctx, strlen(priv->ctx), &tmp_secid); + err = security_secctx_to_secid(priv->ctx, strlen(priv->ctx), &blob); if (err) return err; - if (!tmp_secid) - return -ENOENT; - - err = security_secmark_relabel_packet(tmp_secid); + /* Using le[0] is scaffolding */ + err = security_secmark_relabel_packet(blob.secid[0]); if (err) return err; - priv->secid = tmp_secid; + /* Using le[0] is scaffolding */ + priv->secid = blob.secid[0]; return 0; } diff --git a/net/netfilter/xt_SECMARK.c b/net/netfilter/xt_SECMARK.c index f16202d26c20..8081fadc30e9 100644 --- a/net/netfilter/xt_SECMARK.c +++ b/net/netfilter/xt_SECMARK.c @@ -49,13 +49,14 @@ secmark_tg(struct sk_buff *skb, const struct xt_action_param *par) static int checkentry_lsm(struct xt_secmark_target_info *info) { + struct lsmblob blob; int err; info->secctx[SECMARK_SECCTX_MAX - 1] = '\0'; info->secid = 0; err = security_secctx_to_secid(info->secctx, strlen(info->secctx), - &info->secid); + &blob); if (err) { if (err == -EINVAL) pr_info_ratelimited("invalid security context \'%s\'\n", @@ -63,6 +64,8 @@ static int checkentry_lsm(struct xt_secmark_target_info *info) return err; } + /* scaffolding during the transition */ + info->secid = blob.secid[0]; if (!info->secid) { pr_info_ratelimited("unable to map security context \'%s\'\n", info->secctx); diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c index c92894c3e40a..2976370e41aa 100644 --- a/net/netlabel/netlabel_unlabeled.c +++ b/net/netlabel/netlabel_unlabeled.c @@ -895,7 +895,7 @@ static int netlbl_unlabel_staticadd(struct sk_buff *skb, void *addr; void *mask; u32 addr_len; - u32 secid; + struct lsmblob blob; struct netlbl_audit audit_info; /* Don't allow users to add both IPv4 and IPv6 addresses for a @@ -919,12 +919,13 @@ static int netlbl_unlabel_staticadd(struct sk_buff *skb, ret_val = security_secctx_to_secid( nla_data(info->attrs[NLBL_UNLABEL_A_SECCTX]), nla_len(info->attrs[NLBL_UNLABEL_A_SECCTX]), - &secid); + &blob); if (ret_val != 0) return ret_val; + /* scaffolding with the [0] */ return netlbl_unlhsh_add(&init_net, - dev_name, addr, mask, addr_len, secid, + dev_name, addr, mask, addr_len, blob.secid[0], &audit_info); } @@ -946,7 +947,7 @@ static int netlbl_unlabel_staticadddef(struct sk_buff *skb, void *addr; void *mask; u32 addr_len; - u32 secid; + struct lsmblob blob; struct netlbl_audit audit_info; /* Don't allow users to add both IPv4 and IPv6 addresses for a @@ -968,12 +969,13 @@ static int netlbl_unlabel_staticadddef(struct sk_buff *skb, ret_val = security_secctx_to_secid( nla_data(info->attrs[NLBL_UNLABEL_A_SECCTX]), nla_len(info->attrs[NLBL_UNLABEL_A_SECCTX]), - &secid); + &blob); if (ret_val != 0) return ret_val; + /* scaffolding with the [0] */ return netlbl_unlhsh_add(&init_net, - NULL, addr, mask, addr_len, secid, + NULL, addr, mask, addr_len, blob.secid[0], &audit_info); } diff --git a/security/security.c b/security/security.c index fe76dfa0f2fd..e231fbfd68f2 100644 --- a/security/security.c +++ b/security/security.c @@ -1982,10 +1982,22 @@ int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen) } EXPORT_SYMBOL(security_secid_to_secctx); -int security_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid) +int security_secctx_to_secid(const char *secdata, u32 seclen, + struct lsmblob *blob) { - *secid = 0; - return call_int_hook(secctx_to_secid, 0, secdata, seclen, secid); + struct security_hook_list *hp; + int rc; + + lsmblob_init(blob, 0); + hlist_for_each_entry(hp, &security_hook_heads.secctx_to_secid, list) { + if (WARN_ON(hp->lsmid->slot < 0 || hp->lsmid->slot >= lsm_slot)) + continue; + rc = hp->hook.secctx_to_secid(secdata, seclen, + &blob->secid[hp->lsmid->slot]); + if (rc != 0) + return rc; + } + return 0; } EXPORT_SYMBOL(security_secctx_to_secid); From patchwork Thu Aug 29 23:29:16 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 11122609 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id BCADD14E5 for ; Thu, 29 Aug 2019 23:29:50 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 911182189D for ; Thu, 29 Aug 2019 23:29:50 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="O16pkZVw" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727059AbfH2X3u (ORCPT ); Thu, 29 Aug 2019 19:29:50 -0400 Received: from sonic312-30.consmr.mail.gq1.yahoo.com ([98.137.69.211]:46522 "EHLO sonic312-30.consmr.mail.gq1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727226AbfH2X3t (ORCPT ); Thu, 29 Aug 2019 19:29:49 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1567121387; bh=T0YD3UU8MIp1VgDFQti+JFgyZ4tyEwdhYb6R40QtWAs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=O16pkZVwdFelqUQw8wQnnCGpducupUV0z4gwUF2r3vyGyKDXQ6Vk5gUMvxVqWfTXpUgaHPSWxYGlm99XswIAkBCGnBfV12iENIvsWXlrmHbo0vEqbZB5zdubC5YhKcSL11ianuMqbFBJMXlWKRy2/WtlwqE3YLYYTLSrOiWXCKUgpiZGQZDE5MQ/9h4lv2vuGOdGwHUJqRoJRiXEuoqEYtbCcc73XtqbzKd6IYK0SanZ/boqBQUpmUKoFBRLIVko/blPGuG9Es3UtC0Ai7noN36DF2lMR9meqaEm6oc00n0DKcyZdb7a4totGeOlWCE58wlLSq9cqY8AMXtcYZjxlA== X-YMail-OSG: J.t8dWYVM1nNMJt0tMhXRf2beW4IbRa6fTbhIfkps0lSMTn4Op6ykrFIsboKYCV FtCLU5iucDF9Yixq3ZYiMWi.Cp.ooSobeyU0CpsBvVmpB09fyWO4hJGkkawsEN71wvkXGDu2ycMH 5HZLZ9fX7OhHyrvhbbZye8bT__FfB5jpi8Ydf_ERyfPqoYXgyIxoxwoeNyU7pCfhKShQ8Ry1wZ6c bJNfLNDaQfzwE0GOZXtSt5bbkKhLshRbFZkGApRWTlINJnKWnCIfw.4lsUP8RVpC7VbtLvvJZYT4 JBtG_k8Zd70gW0MPNO2sL0.oYQRQ3._hKNUqH7byCIDvRzbAoLs.sTxbFgzjtfKJ_ZBfhUHVhTn9 q2fqwWkOJOKAYFrbc0w5ZAOhfasunspxgXj.r2taMxI7kuvmFYlZl_x2RfKLo2kPwdDU_vfEBPkY F4OVfuBZKhScl5IPuv3X9bctLZqAUK3ulUSs_p._hYRq1kKmdd4veis68FyaHOlQdRzcdccgM2vZ hL491LNurYPN85Xp1Gr3LOQ_MIU_BJJZGzLcxa1.zjPKeQo_JvgfjciIC5aSW0_ejwocDtverpc9 jijagRQ2bXFAfbqtNQjzhtERdn.l5V_jXCvGkOpo8k3FaTPFadNeIrkMlL5CE.P5j9k2QXCRJkP9 N457By48xeZgjgZ_QjEgnpO1tM3x_k0L2qY.xJumIqo78PWubdu4yuRhvTV_Kai5gwRGpW3L790T L6ibrEv2zDWVmmti6vE.byzySEXhfdAF_RtxfguscHZO5cHtD7cY2Cqc_h.gjaYmf26vd._hCGKm YYXPWyxnj3fd8aID3KuQKnV3UMry688yf7hJ.p3Xl3gtItu_iQFwOMNTy4ICcQFvyY4fpW5g6upV COeym.ravWKzuYuehrrbtQqmlBRR0xHGPkYikx6iovBrKCAylnCuSop142y.dlzEI1.HnkCtAN1p Eb8b94dhYB9gStd5qshyXjRZwSp5hVVT_TYPhkY_WpG80R3A.MZlvB_soXrFk53xnGTaJaq1Wcir 2KYLJYQEpVJ0hip8JvFtdWbuz9JeUKlK2zF9JEr4Jf7O9g2vCRNQpCECj7PMy33RG4uHiOC5GuyU vz4iSPhYVlZdSN24bXyp.QqLV7JxErpsK1uDCUn6nJOb.3qP3axku1NLx53XCLw8O4cRXsUpis7t mtK9Tdpm1qIWw9SXoM_rOUUa3OlHZ8Jy8eKw2V6ykfK6_xCprPX4Miu9yzY1Cqfir8rWZEfe6Snt kCxtvKmzs332Voc0YpWVM4N8U2JeEnLqe_FWljH_yUV532rpbaL01ye7SO.pOgxI69Z7AUMp88Q. L5lW8GA-- Received: from sonic.gate.mail.ne1.yahoo.com by sonic312.consmr.mail.gq1.yahoo.com with HTTP; Thu, 29 Aug 2019 23:29:47 +0000 Received: by smtp412.mail.gq1.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID ded9e12cc42d2f561e2af538140d1439; Thu, 29 Aug 2019 23:29:46 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, jmorris@namei.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org Cc: casey@schaufler-ca.com, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, paul@paul-moore.com, sds@tycho.nsa.gov Subject: [PATCH v8 09/28] LSM: Use lsmblob in security_secid_to_secctx Date: Thu, 29 Aug 2019 16:29:16 -0700 Message-Id: <20190829232935.7099-10-casey@schaufler-ca.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190829232935.7099-1-casey@schaufler-ca.com> References: <20190829232935.7099-1-casey@schaufler-ca.com> MIME-Version: 1.0 Sender: selinux-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: selinux@vger.kernel.org Change security_secid_to_secctx() to take a lsmblob as input instead of a u32 secid. It will then call the LSM hooks using the lsmblob element allocated for that module. The callers have been updated as well. This allows for the possibility that more than one module may be called upon to translate a secid to a string, as can occur in the audit code. Reviewed-by: Kees Cook Reviewed-by: John Johansen Signed-off-by: Casey Schaufler --- drivers/android/binder.c | 4 +++- include/linux/security.h | 5 +++-- include/net/scm.h | 5 ++--- kernel/audit.c | 9 +++++++-- kernel/auditsc.c | 14 ++++++++++---- net/ipv4/ip_sockglue.c | 3 +-- net/netfilter/nf_conntrack_netlink.c | 8 ++++++-- net/netfilter/nf_conntrack_standalone.c | 4 +++- net/netfilter/nfnetlink_queue.c | 8 ++++++-- net/netlabel/netlabel_unlabeled.c | 18 ++++++++++++++---- net/netlabel/netlabel_user.c | 6 +++--- security/security.c | 16 +++++++++++++--- 12 files changed, 71 insertions(+), 29 deletions(-) diff --git a/drivers/android/binder.c b/drivers/android/binder.c index 8685882da64c..1962f6b8abd0 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -3120,9 +3120,11 @@ static void binder_transaction(struct binder_proc *proc, if (target_node && target_node->txn_security_ctx) { u32 secid; + struct lsmblob blob; security_task_getsecid(proc->tsk, &secid); - ret = security_secid_to_secctx(secid, &secctx, &secctx_sz); + lsmblob_init(&blob, secid); + ret = security_secid_to_secctx(&blob, &secctx, &secctx_sz); if (ret) { return_error = BR_FAILED_REPLY; return_error_param = ret; diff --git a/include/linux/security.h b/include/linux/security.h index 30337f1a9056..7b4667cc4930 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -446,7 +446,7 @@ int security_setprocattr(const char *lsm, const char *name, void *value, size_t size); int security_netlink_send(struct sock *sk, struct sk_buff *skb); int security_ismaclabel(const char *name); -int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen); +int security_secid_to_secctx(struct lsmblob *blob, char **secdata, u32 *seclen); int security_secctx_to_secid(const char *secdata, u32 seclen, struct lsmblob *blob); void security_release_secctx(char *secdata, u32 seclen); @@ -1224,7 +1224,8 @@ static inline int security_ismaclabel(const char *name) return 0; } -static inline int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen) +static inline int security_secid_to_secctx(struct lsmblob *blob, + char **secdata, u32 *seclen) { return -EOPNOTSUPP; } diff --git a/include/net/scm.h b/include/net/scm.h index e2e71c4bf9d0..31ae605fcc0a 100644 --- a/include/net/scm.h +++ b/include/net/scm.h @@ -97,9 +97,8 @@ static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct sc int err; if (test_bit(SOCK_PASSSEC, &sock->flags)) { - /* Scaffolding - it has to be element 0 for now */ - err = security_secid_to_secctx(scm->lsmblob.secid[0], - &secdata, &seclen); + err = security_secid_to_secctx(&scm->lsmblob, &secdata, + &seclen); if (!err) { put_cmsg(msg, SOL_SOCKET, SCM_SECURITY, seclen, secdata); diff --git a/kernel/audit.c b/kernel/audit.c index c89ea48c70a6..d0338411d75d 100644 --- a/kernel/audit.c +++ b/kernel/audit.c @@ -1430,7 +1430,10 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) case AUDIT_SIGNAL_INFO: len = 0; if (audit_sig_sid) { - err = security_secid_to_secctx(audit_sig_sid, &ctx, &len); + struct lsmblob blob; + + lsmblob_init(&blob, audit_sig_sid); + err = security_secid_to_secctx(&blob, &ctx, &len); if (err) return err; } @@ -2073,12 +2076,14 @@ int audit_log_task_context(struct audit_buffer *ab) unsigned len; int error; u32 sid; + struct lsmblob blob; security_task_getsecid(current, &sid); if (!sid) return 0; - error = security_secid_to_secctx(sid, &ctx, &len); + lsmblob_init(&blob, sid); + error = security_secid_to_secctx(&blob, &ctx, &len); if (error) { if (error != -EINVAL) goto error_path; diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 18ee5556c086..d31914088a82 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -947,6 +947,7 @@ static int audit_log_pid_context(struct audit_context *context, pid_t pid, char *ctx = NULL; u32 len; int rc = 0; + struct lsmblob blob; ab = audit_log_start(context, GFP_KERNEL, AUDIT_OBJ_PID); if (!ab) @@ -956,7 +957,8 @@ static int audit_log_pid_context(struct audit_context *context, pid_t pid, from_kuid(&init_user_ns, auid), from_kuid(&init_user_ns, uid), sessionid); if (sid) { - if (security_secid_to_secctx(sid, &ctx, &len)) { + lsmblob_init(&blob, sid); + if (security_secid_to_secctx(&blob, &ctx, &len)) { audit_log_format(ab, " obj=(none)"); rc = 1; } else { @@ -1198,7 +1200,10 @@ static void show_special(struct audit_context *context, int *call_panic) if (osid) { char *ctx = NULL; u32 len; - if (security_secid_to_secctx(osid, &ctx, &len)) { + struct lsmblob blob; + + lsmblob_init(&blob, osid); + if (security_secid_to_secctx(&blob, &ctx, &len)) { audit_log_format(ab, " osid=%u", osid); *call_panic = 1; } else { @@ -1349,9 +1354,10 @@ static void audit_log_name(struct audit_context *context, struct audit_names *n, if (n->osid != 0) { char *ctx = NULL; u32 len; + struct lsmblob blob; - if (security_secid_to_secctx( - n->osid, &ctx, &len)) { + lsmblob_init(&blob, n->osid); + if (security_secid_to_secctx(&blob, &ctx, &len)) { audit_log_format(ab, " osid=%u", n->osid); if (call_panic) *call_panic = 2; diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c index 2a5c868ce135..e05f4ef68bd8 100644 --- a/net/ipv4/ip_sockglue.c +++ b/net/ipv4/ip_sockglue.c @@ -139,8 +139,7 @@ static void ip_cmsg_recv_security(struct msghdr *msg, struct sk_buff *skb) if (err) return; - /* Scaffolding - it has to be element 0 */ - err = security_secid_to_secctx(lb.secid[0], &secdata, &seclen); + err = security_secid_to_secctx(&lb, &secdata, &seclen); if (err) return; diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index 66c596d287a5..ca0968f13240 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -330,8 +330,10 @@ static int ctnetlink_dump_secctx(struct sk_buff *skb, const struct nf_conn *ct) struct nlattr *nest_secctx; int len, ret; char *secctx; + struct lsmblob blob; - ret = security_secid_to_secctx(ct->secmark, &secctx, &len); + lsmblob_init(&blob, ct->secmark); + ret = security_secid_to_secctx(&blob, &secctx, &len); if (ret) return 0; @@ -615,8 +617,10 @@ static inline int ctnetlink_secctx_size(const struct nf_conn *ct) { #ifdef CONFIG_NF_CONNTRACK_SECMARK int len, ret; + struct lsmblob blob; - ret = security_secid_to_secctx(ct->secmark, NULL, &len); + lsmblob_init(&blob, ct->secmark); + ret = security_secid_to_secctx(&blob, NULL, &len); if (ret) return 0; diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c index c2ae14c720b4..c793103f3cd7 100644 --- a/net/netfilter/nf_conntrack_standalone.c +++ b/net/netfilter/nf_conntrack_standalone.c @@ -175,8 +175,10 @@ static void ct_show_secctx(struct seq_file *s, const struct nf_conn *ct) int ret; u32 len; char *secctx; + struct lsmblob blob; - ret = security_secid_to_secctx(ct->secmark, &secctx, &len); + lsmblob_init(&blob, ct->secmark); + ret = security_secid_to_secctx(&blob, &secctx, &len); if (ret) return; diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c index 0dcc3592d053..59211bff90ab 100644 --- a/net/netfilter/nfnetlink_queue.c +++ b/net/netfilter/nfnetlink_queue.c @@ -309,13 +309,17 @@ static u32 nfqnl_get_sk_secctx(struct sk_buff *skb, char **secdata) { u32 seclen = 0; #if IS_ENABLED(CONFIG_NETWORK_SECMARK) + struct lsmblob blob; + if (!skb || !sk_fullsock(skb->sk)) return 0; read_lock_bh(&skb->sk->sk_callback_lock); - if (skb->secmark) - security_secid_to_secctx(skb->secmark, secdata, &seclen); + if (skb->secmark) { + lsmblob_init(&blob, skb->secmark); + security_secid_to_secctx(&blob, secdata, &seclen); + } read_unlock_bh(&skb->sk->sk_callback_lock); #endif diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c index 2976370e41aa..2d8dd5b84457 100644 --- a/net/netlabel/netlabel_unlabeled.c +++ b/net/netlabel/netlabel_unlabeled.c @@ -389,6 +389,7 @@ int netlbl_unlhsh_add(struct net *net, struct audit_buffer *audit_buf = NULL; char *secctx = NULL; u32 secctx_len; + struct lsmblob blob; if (addr_len != sizeof(struct in_addr) && addr_len != sizeof(struct in6_addr)) @@ -451,7 +452,8 @@ int netlbl_unlhsh_add(struct net *net, unlhsh_add_return: rcu_read_unlock(); if (audit_buf != NULL) { - if (security_secid_to_secctx(secid, + lsmblob_init(&blob, secid); + if (security_secid_to_secctx(&blob, &secctx, &secctx_len) == 0) { audit_log_format(audit_buf, " sec_obj=%s", secctx); @@ -488,6 +490,7 @@ static int netlbl_unlhsh_remove_addr4(struct net *net, struct net_device *dev; char *secctx; u32 secctx_len; + struct lsmblob blob; spin_lock(&netlbl_unlhsh_lock); list_entry = netlbl_af4list_remove(addr->s_addr, mask->s_addr, @@ -507,8 +510,10 @@ static int netlbl_unlhsh_remove_addr4(struct net *net, addr->s_addr, mask->s_addr); if (dev != NULL) dev_put(dev); + if (entry != NULL) + lsmblob_init(&blob, entry->secid); if (entry != NULL && - security_secid_to_secctx(entry->secid, + security_secid_to_secctx(&blob, &secctx, &secctx_len) == 0) { audit_log_format(audit_buf, " sec_obj=%s", secctx); security_release_secctx(secctx, secctx_len); @@ -550,6 +555,7 @@ static int netlbl_unlhsh_remove_addr6(struct net *net, struct net_device *dev; char *secctx; u32 secctx_len; + struct lsmblob blob; spin_lock(&netlbl_unlhsh_lock); list_entry = netlbl_af6list_remove(addr, mask, &iface->addr6_list); @@ -568,8 +574,10 @@ static int netlbl_unlhsh_remove_addr6(struct net *net, addr, mask); if (dev != NULL) dev_put(dev); + if (entry != NULL) + lsmblob_init(&blob, entry->secid); if (entry != NULL && - security_secid_to_secctx(entry->secid, + security_secid_to_secctx(&blob, &secctx, &secctx_len) == 0) { audit_log_format(audit_buf, " sec_obj=%s", secctx); security_release_secctx(secctx, secctx_len); @@ -1090,6 +1098,7 @@ static int netlbl_unlabel_staticlist_gen(u32 cmd, u32 secid; char *secctx; u32 secctx_len; + struct lsmblob blob; data = genlmsg_put(cb_arg->skb, NETLINK_CB(cb_arg->nl_cb->skb).portid, cb_arg->seq, &netlbl_unlabel_gnl_family, @@ -1144,7 +1153,8 @@ static int netlbl_unlabel_staticlist_gen(u32 cmd, secid = addr6->secid; } - ret_val = security_secid_to_secctx(secid, &secctx, &secctx_len); + lsmblob_init(&blob, secid); + ret_val = security_secid_to_secctx(&blob, &secctx, &secctx_len); if (ret_val != 0) goto list_cb_failure; ret_val = nla_put(cb_arg->skb, diff --git a/net/netlabel/netlabel_user.c b/net/netlabel/netlabel_user.c index 4676f5bb16ae..2ccc6567e2a2 100644 --- a/net/netlabel/netlabel_user.c +++ b/net/netlabel/netlabel_user.c @@ -100,6 +100,7 @@ struct audit_buffer *netlbl_audit_start_common(int type, struct audit_buffer *audit_buf; char *secctx; u32 secctx_len; + struct lsmblob blob; if (audit_enabled == AUDIT_OFF) return NULL; @@ -112,10 +113,9 @@ struct audit_buffer *netlbl_audit_start_common(int type, from_kuid(&init_user_ns, audit_info->loginuid), audit_info->sessionid); + lsmblob_init(&blob, audit_info->secid); if (audit_info->secid != 0 && - security_secid_to_secctx(audit_info->secid, - &secctx, - &secctx_len) == 0) { + security_secid_to_secctx(&blob, &secctx, &secctx_len) == 0) { audit_log_format(audit_buf, " subj=%s", secctx); security_release_secctx(secctx, secctx_len); } diff --git a/security/security.c b/security/security.c index e231fbfd68f2..837c3c6b6e7c 100644 --- a/security/security.c +++ b/security/security.c @@ -1975,10 +1975,20 @@ int security_ismaclabel(const char *name) } EXPORT_SYMBOL(security_ismaclabel); -int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen) +int security_secid_to_secctx(struct lsmblob *blob, char **secdata, u32 *seclen) { - return call_int_hook(secid_to_secctx, -EOPNOTSUPP, secid, secdata, - seclen); + struct security_hook_list *hp; + int rc; + + hlist_for_each_entry(hp, &security_hook_heads.secid_to_secctx, list) { + if (WARN_ON(hp->lsmid->slot < 0 || hp->lsmid->slot >= lsm_slot)) + continue; + rc = hp->hook.secid_to_secctx(blob->secid[hp->lsmid->slot], + secdata, seclen); + if (rc != 0) + return rc; + } + return 0; } EXPORT_SYMBOL(security_secid_to_secctx); From patchwork Thu Aug 29 23:29:17 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 11122625 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 9C9FA1395 for ; Thu, 29 Aug 2019 23:29:56 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 7A9382173E for ; Thu, 29 Aug 2019 23:29:56 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="bmM20i6x" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728122AbfH2X34 (ORCPT ); Thu, 29 Aug 2019 19:29:56 -0400 Received: from sonic303-28.consmr.mail.ne1.yahoo.com ([66.163.188.154]:35963 "EHLO sonic303-28.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727738AbfH2X3z (ORCPT ); Thu, 29 Aug 2019 19:29:55 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1567121394; bh=NqpgYkQbkpDA8SdvAINO7YGHoVQ1J9pYODDE5YAZMOY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=bmM20i6xir/VyI1Jaau7FUFZSM4chAi8V3tZ1RiWYO6O/C663Yk5ZbH7ioT1QtaaBN+6w6HPHuiOfpNeplaSdzmkOyK8y9kbag5SUph/GyjwsIkmHe2smBaD6MVX5Ed9/m+5IlSjPbm2W1qRV0DKUryAQzLOIUZiDMVLfUjI2nOaeWIrbjFxT6gWRjTshUMN7389JDLBeu3/iqKe3RaCQymjmk/UnKaeVwKfAP41fibsZKTdXAGccMPbDZ7NObs4hfqXzQa+hfTsajEdSJ+sXAtUbanj6LKH8iXwouCPKWif/vPjCYv0MLJpmY+0QAEw/hVyw2nyIqLjYSm28GBupg== X-YMail-OSG: kkI.h_4VM1lc2yBN.nfeRIb9ycw76_QBt73RQxznAsQkIeS.uOXhshrSkTtIpOA AwsElvNQb5BH1udRIrcOU2RcwX6ncpPIXfQwVjzr6wOhThnZGe6b3VlmrhMEXOrpxoz2BUyw7R7h WvSp4jjRq3JpC2JwJLx0nfUi7WhIrY.2EfP3xcRULveOgAmJ_fVDUzBODErkN.E6nfTKtMxVE6XU E1bsXvtuITcs.BBbXTvl40T8rPW9Arcfhn7cK57V0MlSzhizvUncQFoE5R.juW2aOwEx7jpGk.Dg pQYfTXdO9Z6cFeBu_Q4ZoiZY6tjRgwdLN2w9oreJNIYtcoh4T1ncLEaWoZ_r3tH_ksOesgsN.wbo MLiAF3U6nLXec1LVHIGYvIvuRxqsVHknZCoRhD4MM9QNdyB3DfEowuk56rZ9Qh.iZjbl6BV_fW.o Tx4ksC_QcNI5tMTg3a8iTRLrfF1fQ94V4uWTOrOif7HrduPjVLVPZLFnEQVsQQDqKoEmLe2KH20z nTxlSzM24ykraCTUQbgjcKgGgn2gwohxcfp0RmUeiAc.UQqYtaKhEmO7FtUpo_1_9k0KI4_yRFNq 528V4tf9Tltwd4lj2SG0S3uWmB_tx1fIJh9XTHOVT0KFaWXXyxrCMMLuRhbJHUx0EHaRuLnup7zv jJoM2Cc5ixX7pmfmVgtbBUMwwDMtBvWhuNq870MiOJHivMw1GPfFsAISl9QswJCAQtBNojZ6jYvY .sNcNp9aQ4tU9vds6BafIiVc.UZVE14kboePVWkLLRWkvI4tN9zEK_nhMH.1pSP7HC7vk.IrE0LO yrTG4DNfIA8f4Iqs7Aqx_Uxi3UHqJAJbDF_ZgqEF54OYYGeqtZED2dHXvnkNqFCodR5YQSG3M1a4 fiC7Q79SE7kr_.eEN.x2Ot5htTZH6VN_wjVqBUQHhY0Ad41dpaWNXG8P55EgzEnWf2fRBUUDrXpV QAAQU_bgMPwjkzfOfrLMoOC.JpzEnIQhZDMGsg49XJr.R0271vRAPE6UY_LWUItBsnvPBFf7VGzT oFFvuUZhjoNkC8IYM8XKC7RaquWy5kTJyx8cJQky278IePhuedmJDjsMikxFLfDEpAQo0oZ0G8cl I1ze.IrFA4n75L0yx66qUz_qTO4TLbD_V8_snVEoYEE96gQPWwHz23v8pWOmzqyTsMiQVEhk5LF4 x7h6x5S8bdmIdtOFbdQRsksVZMqagFRiGVUg6Y4fj9AedCC1opkzIlMAMH5224IMdpdw8KCQWnXC t2xvWdcaZMLyTGFJyTH2ceoGPKmGJkgPU1rPpyp.S16Q8K0zy.XBOTdv2yqSFkTxhlaUFbuI.qAO aR22180X6iBpY Received: from sonic.gate.mail.ne1.yahoo.com by sonic303.consmr.mail.ne1.yahoo.com with HTTP; Thu, 29 Aug 2019 23:29:54 +0000 Received: by smtp416.mail.ne1.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID 0a952b05a9b27bc17439acbca9e87b38; Thu, 29 Aug 2019 23:29:50 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, jmorris@namei.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org Cc: casey@schaufler-ca.com, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, paul@paul-moore.com, sds@tycho.nsa.gov Subject: [PATCH v8 10/28] LSM: Use lsmblob in security_ipc_getsecid Date: Thu, 29 Aug 2019 16:29:17 -0700 Message-Id: <20190829232935.7099-11-casey@schaufler-ca.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190829232935.7099-1-casey@schaufler-ca.com> References: <20190829232935.7099-1-casey@schaufler-ca.com> MIME-Version: 1.0 Sender: selinux-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: selinux@vger.kernel.org There may be more than one LSM that provides IPC data for auditing. Change security_ipc_getsecid() to fill in a lsmblob structure instead of the u32 secid. The audit data structure containing the secid will be updated later, so there is a bit of scaffolding here. Reviewed-by: Kees Cook Reviewed-by: John Johansen Signed-off-by: Casey Schaufler --- include/linux/security.h | 7 ++++--- kernel/auditsc.c | 5 ++++- security/security.c | 12 +++++++++--- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/include/linux/security.h b/include/linux/security.h index 7b4667cc4930..41dc3053094e 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -417,7 +417,7 @@ int security_task_prctl(int option, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5); void security_task_to_inode(struct task_struct *p, struct inode *inode); int security_ipc_permission(struct kern_ipc_perm *ipcp, short flag); -void security_ipc_getsecid(struct kern_ipc_perm *ipcp, u32 *secid); +void security_ipc_getsecid(struct kern_ipc_perm *ipcp, struct lsmblob *blob); int security_msg_msg_alloc(struct msg_msg *msg); void security_msg_msg_free(struct msg_msg *msg); int security_msg_queue_alloc(struct kern_ipc_perm *msq); @@ -1102,9 +1102,10 @@ static inline int security_ipc_permission(struct kern_ipc_perm *ipcp, return 0; } -static inline void security_ipc_getsecid(struct kern_ipc_perm *ipcp, u32 *secid) +static inline void security_ipc_getsecid(struct kern_ipc_perm *ipcp, + struct lsmblob *blob) { - *secid = 0; + lsmblob_init(blob, 0); } static inline int security_msg_msg_alloc(struct msg_msg *msg) diff --git a/kernel/auditsc.c b/kernel/auditsc.c index d31914088a82..148733ec3c72 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -2268,11 +2268,14 @@ void __audit_mq_getsetattr(mqd_t mqdes, struct mq_attr *mqstat) void __audit_ipc_obj(struct kern_ipc_perm *ipcp) { struct audit_context *context = audit_context(); + struct lsmblob blob; context->ipc.uid = ipcp->uid; context->ipc.gid = ipcp->gid; context->ipc.mode = ipcp->mode; context->ipc.has_perm = 0; - security_ipc_getsecid(ipcp, &context->ipc.osid); + security_ipc_getsecid(ipcp, &blob); + /* scaffolding on the [0] - change "osid" to a lsmblob */ + context->ipc.osid = blob.secid[0]; context->type = AUDIT_IPC; } diff --git a/security/security.c b/security/security.c index 837c3c6b6e7c..b4789c31e532 100644 --- a/security/security.c +++ b/security/security.c @@ -1795,10 +1795,16 @@ int security_ipc_permission(struct kern_ipc_perm *ipcp, short flag) return call_int_hook(ipc_permission, 0, ipcp, flag); } -void security_ipc_getsecid(struct kern_ipc_perm *ipcp, u32 *secid) +void security_ipc_getsecid(struct kern_ipc_perm *ipcp, struct lsmblob *blob) { - *secid = 0; - call_void_hook(ipc_getsecid, ipcp, secid); + struct security_hook_list *hp; + + lsmblob_init(blob, 0); + hlist_for_each_entry(hp, &security_hook_heads.ipc_getsecid, list) { + if (WARN_ON(hp->lsmid->slot < 0 || hp->lsmid->slot >= lsm_slot)) + continue; + hp->hook.ipc_getsecid(ipcp, &blob->secid[hp->lsmid->slot]); + } } int security_msg_msg_alloc(struct msg_msg *msg) From patchwork Thu Aug 29 23:29:18 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 11122617 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 7E5071395 for ; Thu, 29 Aug 2019 23:29:54 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 4958E2173E for ; Thu, 29 Aug 2019 23:29:54 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="trg8dWGU" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728017AbfH2X3x (ORCPT ); Thu, 29 Aug 2019 19:29:53 -0400 Received: from sonic311-31.consmr.mail.ne1.yahoo.com ([66.163.188.212]:37289 "EHLO sonic311-31.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727701AbfH2X3x (ORCPT ); Thu, 29 Aug 2019 19:29:53 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1567121391; bh=sZLZcqDLXjHGG+OTnhul6miLPONlWzEpDQClgCPdkKk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=trg8dWGUbyPI42rQBu3CGci+NyDjD5+Xq+k/SiqSnVhW+ku5PFVsn/8EYECTyhnJAnZb+EAeCsbjsUYskgv86QLrMjeFdjc0YiUzjBxZFiPu0F+KE0NdO5imhKN9EPZAonNKywZ0YA20J/M9lJe/rc1wgrpRA1S7p2d3YB7j0r4oqSmczfXW7oXhhCEUgVzwZw+4f4GvJ7jGwCoAoJNJhYINfBOspunF4uOZpERptNirMbK1rNSFCKgYRJyCYei5u9GQ741m9DuMeC75LmfrZVFzd434rOQFAS/lAyrURfD7PEN6kOoVrrymxBBiD24Y3tQiMcDeQY6ApaS2lmrWeA== X-YMail-OSG: OEHl6x4VM1miG7_IhueOeyzXbpMNtp6eGjrk1LDjRBCUjZyKCwSZas55hgJMpYN DGUCxeNZNsYX3F_Emn8RlCTh8QJyjETLxVh1mmiAXVIC9pLrvOTha9sEd2k.gIjylVNpZ3mYlWXn pAHN2pTX8kwxC4rBZnFjspcJDlzQqoaQ6v92wFNXbgdXm.5aTi7z4chv7uPKC9ylLfOabqiIW7se MuYMJZ.YiWFrJxLH8jRNocgyWUtWOkcezvIEj_IbTBXqolDA8zTVD8EEUJDxStAl1_4QWXNIWyno ny0ihwskvFR2O9.wfWSTB3WSy_24uqtZ0wUmbrGYBlsJ0p_UwXfDNOOirAU_CDx2sSVkbyssRoW0 wJvTtXSS3Y8VvYMl.7JVXiyjllPtS3Ic9ojAfKMa6DtYIbqYvx2pAhEn3uaQqNxdpY1cQhJEx19V cE7OnW9ZXPPD69wqar3bX1zzA96TGITrXSlNe.V6FD0G5aNExGfX2_b1qhjBNP7h1BCuxolF7Ebi .3P7_.oonv5_NHPRhjJv0tHjz22j7m3dcfG7rM0lYnNMghK1GJ_LmQiH8NS.ALZmheMayHOszGRZ 3tGU2JSPWxtFXgNuEEJOvxUdkAc1JodwYqyUCJ7JTi1QOGc23Tu482Ny.8GpE8u7IQmMJyhFCwoO 8k4l5z3_hESIi38OP4zhOG.RaznGi7OBEQ49ZTPXTUCwra6EdqUzPspt2NwcW4PSWiLZZ0QNusrI IDmHFOdCWlNaHXpxl5Wzw4Uy6gSgJaGsljYQvVh1tHhBcnGGDa_xhtSPoBg1jkqpgrhlsDsm1Un_ EvOjqkOpDBrDbho8CR74_MEjbGFRyz3AMmL45j.UVaSAphAO166ccQPJtbeV4ADzI.E232P1pDeA jX3Ju0_4.0e_hyYEloYR20Dt0SsvGJ3K4wdZODdxT6a0iEATpPsnPxtGn9XFeel5S1ljWAJnQfeY .YIx4VrFjm88G.6gg83EO3cKAQw04XpRIl98vc2_vwLCfpsYTNI0pJqajwMPCiHUNT0vceSo0Mm_ Saa57XpPSaL2JS_45j0.ADKD9DWm9kiHxwibL3jy5S5fDsm5sz4uQcw75oAEdZvkYCde229iPc0V FJhsZCMrLL7YSvQ.1sFOasnJYbzzk0ZuuQdgXX7KtL6TTrR0AFBu6LteG6FCB1fNNERZ3Jl3Mq1u o6T1mWZ1WpGaITHq.1ob2jN9dgaW8amvgNauFEp8Gpw4RCArUbCSxKKtQZ0cPCeY_sLz7dj1m_YW xpWTw9AihdUt_P7XUg.8N9hjISsg8S4UhsdAhjhGZMQS_VgtcwHFhGlf_V9My.8YiYWusplYwPV8 4NulV28Bt Received: from sonic.gate.mail.ne1.yahoo.com by sonic311.consmr.mail.ne1.yahoo.com with HTTP; Thu, 29 Aug 2019 23:29:51 +0000 Received: by smtp416.mail.ne1.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID 0a952b05a9b27bc17439acbca9e87b38; Thu, 29 Aug 2019 23:29:51 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, jmorris@namei.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org Cc: casey@schaufler-ca.com, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, paul@paul-moore.com, sds@tycho.nsa.gov Subject: [PATCH v8 11/28] LSM: Use lsmblob in security_task_getsecid Date: Thu, 29 Aug 2019 16:29:18 -0700 Message-Id: <20190829232935.7099-12-casey@schaufler-ca.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190829232935.7099-1-casey@schaufler-ca.com> References: <20190829232935.7099-1-casey@schaufler-ca.com> MIME-Version: 1.0 Sender: selinux-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: selinux@vger.kernel.org Change the security_task_getsecid() interface to fill in a lsmblob structure instead of a u32 secid in support of LSM stacking. Audit interfaces will need to collect all possible secids for possible reporting. Reviewed-by: Kees Cook Reviewed-by: John Johansen Signed-off-by: Casey Schaufler --- drivers/android/binder.c | 4 +--- include/linux/security.h | 7 +++--- kernel/audit.c | 6 ++--- kernel/auditfilter.c | 4 +--- kernel/auditsc.c | 22 ++++++++++++------ net/netlabel/netlabel_unlabeled.c | 5 +++- net/netlabel/netlabel_user.h | 6 ++++- security/integrity/ima/ima_appraise.c | 4 +++- security/integrity/ima/ima_main.c | 33 +++++++++++++++------------ security/security.c | 12 +++++++--- 10 files changed, 63 insertions(+), 40 deletions(-) diff --git a/drivers/android/binder.c b/drivers/android/binder.c index 1962f6b8abd0..144ac4f1c24f 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -3119,11 +3119,9 @@ static void binder_transaction(struct binder_proc *proc, t->priority = task_nice(current); if (target_node && target_node->txn_security_ctx) { - u32 secid; struct lsmblob blob; - security_task_getsecid(proc->tsk, &secid); - lsmblob_init(&blob, secid); + security_task_getsecid(proc->tsk, &blob); ret = security_secid_to_secctx(&blob, &secctx, &secctx_sz); if (ret) { return_error = BR_FAILED_REPLY; diff --git a/include/linux/security.h b/include/linux/security.h index 41dc3053094e..cfd7cf4b0be9 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -400,7 +400,7 @@ int security_task_fix_setuid(struct cred *new, const struct cred *old, int security_task_setpgid(struct task_struct *p, pid_t pgid); int security_task_getpgid(struct task_struct *p); int security_task_getsid(struct task_struct *p); -void security_task_getsecid(struct task_struct *p, u32 *secid); +void security_task_getsecid(struct task_struct *p, struct lsmblob *blob); int security_task_setnice(struct task_struct *p, int nice); int security_task_setioprio(struct task_struct *p, int ioprio); int security_task_getioprio(struct task_struct *p); @@ -1029,9 +1029,10 @@ static inline int security_task_getsid(struct task_struct *p) return 0; } -static inline void security_task_getsecid(struct task_struct *p, u32 *secid) +static inline void security_task_getsecid(struct task_struct *p, + struct lsmblob *blob) { - *secid = 0; + lsmblob_init(blob, 0); } static inline int security_task_setnice(struct task_struct *p, int nice) diff --git a/kernel/audit.c b/kernel/audit.c index d0338411d75d..a0205f3c23c7 100644 --- a/kernel/audit.c +++ b/kernel/audit.c @@ -2075,14 +2075,12 @@ int audit_log_task_context(struct audit_buffer *ab) char *ctx = NULL; unsigned len; int error; - u32 sid; struct lsmblob blob; - security_task_getsecid(current, &sid); - if (!sid) + security_task_getsecid(current, &blob); + if (!lsmblob_is_set(&blob)) return 0; - lsmblob_init(&blob, sid); error = security_secid_to_secctx(&blob, &ctx, &len); if (error) { if (error != -EINVAL) diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c index 8786b95b60bd..8f244c98bb57 100644 --- a/kernel/auditfilter.c +++ b/kernel/auditfilter.c @@ -1323,7 +1323,6 @@ int audit_filter(int msgtype, unsigned int listtype) for (i = 0; i < e->rule.field_count; i++) { struct audit_field *f = &e->rule.fields[i]; pid_t pid; - u32 sid; struct lsmblob blob; switch (f->type) { @@ -1354,8 +1353,7 @@ int audit_filter(int msgtype, unsigned int listtype) case AUDIT_SUBJ_SEN: case AUDIT_SUBJ_CLR: if (f->lsm_rule) { - security_task_getsecid(current, &sid); - lsmblob_init(&blob, sid); + security_task_getsecid(current, &blob); result = security_audit_rule_match( &blob, f->type, f->op, f->lsm_rule); diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 148733ec3c72..7112fe31684d 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -444,7 +444,6 @@ static int audit_filter_rules(struct task_struct *tsk, { const struct cred *cred; int i, need_sid = 1; - u32 sid; struct lsmblob blob; unsigned int sessionid; @@ -628,10 +627,9 @@ static int audit_filter_rules(struct task_struct *tsk, logged upon error */ if (f->lsm_rule) { if (need_sid) { - security_task_getsecid(tsk, &sid); + security_task_getsecid(tsk, &blob); need_sid = 0; } - lsmblob_init(&blob, sid); result = security_audit_rule_match(&blob, f->type, f->op, @@ -2365,12 +2363,15 @@ int __audit_sockaddr(int len, void *a) void __audit_ptrace(struct task_struct *t) { struct audit_context *context = audit_context(); + struct lsmblob blob; context->target_pid = task_tgid_nr(t); context->target_auid = audit_get_loginuid(t); context->target_uid = task_uid(t); context->target_sessionid = audit_get_sessionid(t); - security_task_getsecid(t, &context->target_sid); + security_task_getsecid(t, &blob); + /* scaffolding - until target_sid is converted */ + context->target_sid = blob.secid[0]; memcpy(context->target_comm, t->comm, TASK_COMM_LEN); } @@ -2387,6 +2388,7 @@ int audit_signal_info(int sig, struct task_struct *t) struct audit_aux_data_pids *axp; struct audit_context *ctx = audit_context(); kuid_t uid = current_uid(), auid, t_uid = task_uid(t); + struct lsmblob blob; if (auditd_test_task(t) && (sig == SIGTERM || sig == SIGHUP || @@ -2397,7 +2399,9 @@ int audit_signal_info(int sig, struct task_struct *t) audit_sig_uid = auid; else audit_sig_uid = uid; - security_task_getsecid(current, &audit_sig_sid); + security_task_getsecid(current, &blob); + /* scaffolding until audit_sig_sid is converted */ + audit_sig_sid = blob.secid[0]; } if (!audit_signals || audit_dummy_context()) @@ -2410,7 +2414,9 @@ int audit_signal_info(int sig, struct task_struct *t) ctx->target_auid = audit_get_loginuid(t); ctx->target_uid = t_uid; ctx->target_sessionid = audit_get_sessionid(t); - security_task_getsecid(t, &ctx->target_sid); + security_task_getsecid(t, &blob); + /* scaffolding until target_sid is converted */ + ctx->target_sid = blob.secid[0]; memcpy(ctx->target_comm, t->comm, TASK_COMM_LEN); return 0; } @@ -2431,7 +2437,9 @@ int audit_signal_info(int sig, struct task_struct *t) axp->target_auid[axp->pid_count] = audit_get_loginuid(t); axp->target_uid[axp->pid_count] = t_uid; axp->target_sessionid[axp->pid_count] = audit_get_sessionid(t); - security_task_getsecid(t, &axp->target_sid[axp->pid_count]); + security_task_getsecid(t, &blob); + /* scaffolding until target_sid is converted */ + axp->target_sid[axp->pid_count] = blob.secid[0]; memcpy(axp->target_comm[axp->pid_count], t->comm, TASK_COMM_LEN); axp->pid_count++; diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c index 2d8dd5b84457..2294aa9471e6 100644 --- a/net/netlabel/netlabel_unlabeled.c +++ b/net/netlabel/netlabel_unlabeled.c @@ -1552,11 +1552,14 @@ int __init netlbl_unlabel_defconf(void) int ret_val; struct netlbl_dom_map *entry; struct netlbl_audit audit_info; + struct lsmblob blob; /* Only the kernel is allowed to call this function and the only time * it is called is at bootup before the audit subsystem is reporting * messages so don't worry to much about these values. */ - security_task_getsecid(current, &audit_info.secid); + security_task_getsecid(current, &blob); + /* scaffolding until audit_info.secid is converted */ + audit_info.secid = blob.secid[0]; audit_info.loginuid = GLOBAL_ROOT_UID; audit_info.sessionid = 0; diff --git a/net/netlabel/netlabel_user.h b/net/netlabel/netlabel_user.h index 4a397cde1a48..ab88baaaa50d 100644 --- a/net/netlabel/netlabel_user.h +++ b/net/netlabel/netlabel_user.h @@ -48,7 +48,11 @@ static inline void netlbl_netlink_auditinfo(struct sk_buff *skb, struct netlbl_audit *audit_info) { - security_task_getsecid(current, &audit_info->secid); + struct lsmblob blob; + + security_task_getsecid(current, &blob); + /* scaffolding until secid is converted */ + audit_info->secid = blob.secid[0]; audit_info->loginuid = audit_get_loginuid(current); audit_info->sessionid = audit_get_sessionid(current); } diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c index 5fb7127bbe68..85c7692fc4a3 100644 --- a/security/integrity/ima/ima_appraise.c +++ b/security/integrity/ima/ima_appraise.c @@ -51,11 +51,13 @@ bool is_ima_appraise_enabled(void) int ima_must_appraise(struct inode *inode, int mask, enum ima_hooks func) { u32 secid; + struct lsmblob blob; if (!ima_appraise) return 0; - security_task_getsecid(current, &secid); + security_task_getsecid(current, &blob); + lsmblob_secid(&blob, &secid); return ima_match_policy(inode, current_cred(), secid, func, mask, IMA_APPRAISE | IMA_HASH, NULL); } diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c index 357edd140c09..fefa848cf0c7 100644 --- a/security/integrity/ima/ima_main.c +++ b/security/integrity/ima/ima_main.c @@ -335,12 +335,13 @@ static int process_measurement(struct file *file, const struct cred *cred, */ int ima_file_mmap(struct file *file, unsigned long prot) { - u32 secid; + struct lsmblob blob; if (file && (prot & PROT_EXEC)) { - security_task_getsecid(current, &secid); - return process_measurement(file, current_cred(), secid, NULL, - 0, MAY_EXEC, MMAP_CHECK); + security_task_getsecid(current, &blob); + /* scaffolding - until process_measurement changes */ + return process_measurement(file, current_cred(), blob.secid[0], + NULL, 0, MAY_EXEC, MMAP_CHECK); } return 0; @@ -363,10 +364,12 @@ int ima_bprm_check(struct linux_binprm *bprm) { int ret; u32 secid; + struct lsmblob blob; - security_task_getsecid(current, &secid); - ret = process_measurement(bprm->file, current_cred(), secid, NULL, 0, - MAY_EXEC, BPRM_CHECK); + security_task_getsecid(current, &blob); + /* scaffolding until process_measurement changes */ + ret = process_measurement(bprm->file, current_cred(), blob.secid[0], + NULL, 0, MAY_EXEC, BPRM_CHECK); if (ret) return ret; @@ -387,10 +390,11 @@ int ima_bprm_check(struct linux_binprm *bprm) */ int ima_file_check(struct file *file, int mask) { - u32 secid; + struct lsmblob blob; - security_task_getsecid(current, &secid); - return process_measurement(file, current_cred(), secid, NULL, 0, + security_task_getsecid(current, &blob); + /* scaffolding until process_measurement changes */ + return process_measurement(file, current_cred(), blob.secid[0], NULL, 0, mask & (MAY_READ | MAY_WRITE | MAY_EXEC | MAY_APPEND), FILE_CHECK); } @@ -499,7 +503,7 @@ int ima_post_read_file(struct file *file, void *buf, loff_t size, enum kernel_read_file_id read_id) { enum ima_hooks func; - u32 secid; + struct lsmblob blob; if (!file && read_id == READING_FIRMWARE) { if ((ima_appraise & IMA_APPRAISE_FIRMWARE) && @@ -521,9 +525,10 @@ int ima_post_read_file(struct file *file, void *buf, loff_t size, } func = read_idmap[read_id] ?: FILE_CHECK; - security_task_getsecid(current, &secid); - return process_measurement(file, current_cred(), secid, buf, size, - MAY_READ, func); + security_task_getsecid(current, &blob); + /* scaffolding until process_measurement changes */ + return process_measurement(file, current_cred(), blob.secid[0], buf, + size, MAY_READ, func); } /** diff --git a/security/security.c b/security/security.c index b4789c31e532..43076ae0373f 100644 --- a/security/security.c +++ b/security/security.c @@ -1712,10 +1712,16 @@ int security_task_getsid(struct task_struct *p) return call_int_hook(task_getsid, 0, p); } -void security_task_getsecid(struct task_struct *p, u32 *secid) +void security_task_getsecid(struct task_struct *p, struct lsmblob *blob) { - *secid = 0; - call_void_hook(task_getsecid, p, secid); + struct security_hook_list *hp; + + lsmblob_init(blob, 0); + hlist_for_each_entry(hp, &security_hook_heads.task_getsecid, list) { + if (WARN_ON(hp->lsmid->slot < 0 || hp->lsmid->slot >= lsm_slot)) + continue; + hp->hook.task_getsecid(p, &blob->secid[hp->lsmid->slot]); + } } EXPORT_SYMBOL(security_task_getsecid); From patchwork Thu Aug 29 23:29:19 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 11122621 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id D50FD18EC for ; Thu, 29 Aug 2019 23:29:54 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id B23832173E for ; Thu, 29 Aug 2019 23:29:54 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="bf6aF+xG" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727551AbfH2X3y (ORCPT ); Thu, 29 Aug 2019 19:29:54 -0400 Received: from sonic307-16.consmr.mail.ne1.yahoo.com ([66.163.190.39]:41393 "EHLO sonic307-16.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727738AbfH2X3x (ORCPT ); Thu, 29 Aug 2019 19:29:53 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1567121392; bh=uxcHwgOpzC/adUgk2d3S1gEWM4FTxZpivBefUTTskGw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=bf6aF+xGOkK2FLhLalqDnfQ0uAgiOCRVXH4AP6RgQrOq7huFazdsp/Q9D9iQc7ICuQO9zWSwCV/K4KMd7evUZRn5QvAIm0BsGb03JZZXOBqbaM8xTb/pSOst8mpZ3vJCfiiwGTrsXHiRdzBCH+hEirqEAuaYD1v6npnjC1wcDJZE3AMWOCaNCfgoTCZc0YYEpgzvupyUOKiJKKgUqGwABy38fL8dGb/sK6J3xoxTCvOc6+WwoTtxBmUAPCCTlizyi3/J0yB4y895Fuj1UJ5ZWg76GL0oudCAb+UJSe7b30I+a6VBbKjSmm8HANoC0Sm+SUstvaUJf0X2/0BZOWviTg== X-YMail-OSG: pnnz.YMVM1k1BiSBcI3lsYS9LT_HaWcG5eegHolFgg64h2niY_ZYEjuU2yLrLug jFAclqmxUf6t8kVFOKtyEZkIIWqr._ixGA_kd4tWXv9lQGPFo1gsAuiBWEZ_S36CYwEtkyWBWFTm IVzyMsnQUS8EPEgwnMhFSc4a8G3W4neVYHT1FAG4_vKFdzwHmTYMv6cExc77x8kjSJUdCKaJs.7d Bbh1VfbkPcaHTkSakF7vjSmgMqHd8sBM9KvVMbdWkvsf4oceAAbryWCykqQ74iNU6i7y5MKaGsbx _mOfCNYRSsksvaahtzShZsd0U1jaRMgjYE_N3YBz.FlsfiukKfQ5hhjqnD0nNgzkyLbpme45VbY7 MvO3edCFzWI13GZusT4VFZpBCB6KfBRZSMXxhfYbEFiyevpBC1pnRKa0.9Hhs9aZjKOj525yNdeL 9IT385uJhAblFp8.4Jlwng6oLu4N5zPXKuhDle8pKSflHLMZKX1X0DKhrEBvbwlaoVRkXDjxmbgn 5HfbXUGFhERTuf0svL7BKBOInwkl3vZn0qMYuPXZIhQWV9w9ct4CEAlVYaiiV0Ov19WzJNKoNX3V PF4ppnNai2kcX7SxlR5ynbAUTLtCP48wXh0jjEiFm4ag536W6B8cw7dIooxiAk4_VkcflWrPXY4o uyuZgtj33BfXE6CC8L4iVrdwT3yI1w2YMbSQt1wKBiArekZAy4M5j.nIjgEo24LzXlCCbSKgsLi7 pKF16q5Q6kKOIPq_h2pduEpNNPJV9jNhfSAM1jyZgEzcWFS751GDN_NrkSslfG084awnBfGoQArB KqwAczkQIXNxTnTbogfsYC_DluCtorrXdTBSHah5QI8drchIadzSUiIfDPoCF7VEP.Vv2KxTTIva 3bLotKUnJGUk44IXiFssfVd45istbfv1PgRHttk9di8u7dPjmwEPcX1OEMc6LADM0wfPhYs_V0s. 49W9NZfQEehNHhYLH3tF_x9Iz_TGqZafwA4KD1aJdL2cd6vl_CTA4YwtYkEQfRw_CCQ_0N1wXXy4 NRtXMoYolh7pKdIBPrh_LrEJfggj3yhyENce_7ifEIAKWJESmNh3eu4zUkSMuyF7cS_6_5tfzhRY 87uh9YBvhkUEyUECPtbNcOxfFcnR0L7LcTbjyb3NRxHH3LPoSXWgQJHP.C9KwRzcaeQPsqAVy_cz b9Z7kRkiptTCwnRfwo9k0CUJppgMTi9jE7LuD9hsROKYXE_IiPsECTE00URwfdqjjE7tVwY0DPhR YlUvCL1Avu6aAB4.E.YCC.jOT81kfWLe7i0D4C7YT26HXdwI1jjmuYpvDG.KvOqfaoEa0KnU.40N GXqdll7Cq Received: from sonic.gate.mail.ne1.yahoo.com by sonic307.consmr.mail.ne1.yahoo.com with HTTP; Thu, 29 Aug 2019 23:29:52 +0000 Received: by smtp416.mail.ne1.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID 0a952b05a9b27bc17439acbca9e87b38; Thu, 29 Aug 2019 23:29:51 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, jmorris@namei.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org Cc: casey@schaufler-ca.com, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, paul@paul-moore.com, sds@tycho.nsa.gov Subject: [PATCH v8 12/28] LSM: Use lsmblob in security_inode_getsecid Date: Thu, 29 Aug 2019 16:29:19 -0700 Message-Id: <20190829232935.7099-13-casey@schaufler-ca.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190829232935.7099-1-casey@schaufler-ca.com> References: <20190829232935.7099-1-casey@schaufler-ca.com> MIME-Version: 1.0 Sender: selinux-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: selinux@vger.kernel.org Change the security_inode_getsecid() interface to fill in a lsmblob structure instead of a u32 secid. This allows for its callers to gather data from all registered LSMs. Data is provided for IMA and audit. Reviewed-by: Kees Cook Reviewed-by: John Johansen Signed-off-by: Casey Schaufler --- include/linux/security.h | 7 ++++--- kernel/auditsc.c | 6 +++++- security/integrity/ima/ima_policy.c | 4 +--- security/security.c | 11 +++++++++-- 4 files changed, 19 insertions(+), 9 deletions(-) diff --git a/include/linux/security.h b/include/linux/security.h index cfd7cf4b0be9..2d81cac418e3 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -362,7 +362,7 @@ int security_inode_killpriv(struct dentry *dentry); int security_inode_getsecurity(struct inode *inode, const char *name, void **buffer, bool alloc); int security_inode_setsecurity(struct inode *inode, const char *name, const void *value, size_t size, int flags); int security_inode_listsecurity(struct inode *inode, char *buffer, size_t buffer_size); -void security_inode_getsecid(struct inode *inode, u32 *secid); +void security_inode_getsecid(struct inode *inode, struct lsmblob *blob); int security_inode_copy_up(struct dentry *src, struct cred **new); int security_inode_copy_up_xattr(const char *name); int security_file_permission(struct file *file, int mask); @@ -858,9 +858,10 @@ static inline int security_inode_listsecurity(struct inode *inode, char *buffer, return 0; } -static inline void security_inode_getsecid(struct inode *inode, u32 *secid) +static inline void security_inode_getsecid(struct inode *inode, + struct lsmblob *blob) { - *secid = 0; + lsmblob_init(blob, 0); } static inline int security_inode_copy_up(struct dentry *src, struct cred **new) diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 7112fe31684d..54797c0fc3b7 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -1910,13 +1910,17 @@ static inline int audit_copy_fcaps(struct audit_names *name, void audit_copy_inode(struct audit_names *name, const struct dentry *dentry, struct inode *inode, unsigned int flags) { + struct lsmblob blob; + name->ino = inode->i_ino; name->dev = inode->i_sb->s_dev; name->mode = inode->i_mode; name->uid = inode->i_uid; name->gid = inode->i_gid; name->rdev = inode->i_rdev; - security_inode_getsecid(inode, &name->osid); + security_inode_getsecid(inode, &blob); + /* scaffolding until osid is updated */ + name->osid = blob.secid[0]; if (flags & AUDIT_INODE_NOEVAL) { name->fcap_ver = -1; return; diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c index e7b8ce942950..92ee3d984c73 100644 --- a/security/integrity/ima/ima_policy.c +++ b/security/integrity/ima/ima_policy.c @@ -326,7 +326,6 @@ static bool ima_match_rules(struct ima_rule_entry *rule, struct inode *inode, return false; for (i = 0; i < MAX_LSM_RULES; i++) { int rc = 0; - u32 osid; struct lsmblob blob; int retried = 0; @@ -337,8 +336,7 @@ static bool ima_match_rules(struct ima_rule_entry *rule, struct inode *inode, case LSM_OBJ_USER: case LSM_OBJ_ROLE: case LSM_OBJ_TYPE: - security_inode_getsecid(inode, &osid); - lsmblob_init(&blob, osid); + security_inode_getsecid(inode, &blob); rc = security_filter_rule_match(&blob, rule->lsm[i].type, Audit_equal, diff --git a/security/security.c b/security/security.c index 43076ae0373f..745e8791b6e3 100644 --- a/security/security.c +++ b/security/security.c @@ -1404,9 +1404,16 @@ int security_inode_listsecurity(struct inode *inode, char *buffer, size_t buffer } EXPORT_SYMBOL(security_inode_listsecurity); -void security_inode_getsecid(struct inode *inode, u32 *secid) +void security_inode_getsecid(struct inode *inode, struct lsmblob *blob) { - call_void_hook(inode_getsecid, inode, secid); + struct security_hook_list *hp; + + lsmblob_init(blob, 0); + hlist_for_each_entry(hp, &security_hook_heads.inode_getsecid, list) { + if (WARN_ON(hp->lsmid->slot < 0 || hp->lsmid->slot >= lsm_slot)) + continue; + hp->hook.inode_getsecid(inode, &blob->secid[hp->lsmid->slot]); + } } int security_inode_copy_up(struct dentry *src, struct cred **new) From patchwork Thu Aug 29 23:29:20 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 11122635 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 6C19614DE for ; Thu, 29 Aug 2019 23:30:00 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 40F8621874 for ; Thu, 29 Aug 2019 23:30:00 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="UqGsIys1" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727985AbfH2X37 (ORCPT ); Thu, 29 Aug 2019 19:29:59 -0400 Received: from sonic311-31.consmr.mail.ne1.yahoo.com ([66.163.188.212]:36662 "EHLO sonic311-31.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728129AbfH2X37 (ORCPT ); Thu, 29 Aug 2019 19:29:59 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1567121396; bh=8buKJ9Ehk8WdISUxNXlvg6ue7BawLz1JjuDKVRMthQ8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=UqGsIys1BXlOfJUBwxPkaZ9UNU0rrWLn+v86BT/Yen9szJSIV1jq0pffYWrU+decmAbc6DdZ2WB7Km3FpM8WYphoazUO5w7VI5IR77wRRWY7CKWnDx+yL5dtdeGffO1FOQ6fRmPzdD00OSObhMOoGffqWzU1Ls+MOYFLYDMAAWBqWFu/lkMWFQQ8FqmCWTHQFy8JQVKx+zDZobnedKaKkStQioUn9p/E5LssuqjpUzEPqB4ME7i+gIqXpwx30XLhWHu6bxbeg8qHlpUY6l7BBj1zKa2a4KI1f3UE29ovjRYMyL3F2f3ov2lg76JyucLW3GB3TUKXnYhGtTCf6Te5SA== X-YMail-OSG: ity40S0VM1l36cRXgP36yn6A.shov1pdKULPRp9IXAnBIDQFYz_xhFdzOv9hqqD 4mbQKZvSRLu2IJ8z6W0S0M.aH3RZwltFZe0ziM.IT_iWTqqN8byNM8sGtJM0SOLvsJPWJ8JJzyxE uBzZcikZ2.tL9cZ840OtEC0oc1LtMNASzuhL6ulSOPk9AKqBX2Gx8FiNc8FxYnjQwX.n8ny3IYNG rvzxe.U9yPFKDrOa5i__5NDFJSPtGY1FNequLHNmpfp_CqCPnMRNTGMRrehTtQx7Q8fHqOSh6G6k g0HZNdz7rEb894spMx1dkQhxiW3NQ7I.j6ry2Tmg5b00oGX8Y0ngommFMKU2NkyJTBvAEP19TuQE fRUfiBAySFY5fqxDNIgvJhRPhXb3.TXRMkDtn_yN01IGSqIxCyt7G_KARZ5IAYdE5zIqxTLvLeQx 3gVWc4f678lUqazG2JUy2r2m_VPK.z_rp3eDGpbnIb_AyMi.bX7lGxDptbKTpmN6GOjeorZnFJZ2 BgFsUVDISPZVV8pikjtni6fDVNMMGrp16gb3VRK9FXLFw9jZOb0Pr8YTHkAPXCWfzk9bY75gsEUy 9Ihnd4CJEZPLRpxh45rxLdQwRnLVQNlZ8FRynEI1MeQYglCZHi6GxIssQcNFpb80cozzyw2prTvv FqjCHn_r7VDEZUdDRp8c7Ac39lmyY7.El5DgSqlmM9uBkQeT4ZXgUwh08nduYxR92YPoUoa4W0hD 3iAW7kunvRTxoUJ39vR20jO7YAqmz.s_k3jMk1FmUQbBsqfoqXWuuY0dCo6zQ1fCNw6rvaba3vw_ .h6xt0pGkdO1CekxqPXZCOA20NNxnBbN4QyXKHwhytOeiecFDJLVHFg.m97rjigS34pW8aVwzk2N 5HFBMxsvqxI3vzdVbJW1J.jPty6JMRLwB8qme15KbVQYxeMXdugbPAefen5S1Irq8kwU8Y9wSRAK 9ICg5s8q5kiX9PfxyeVylAcbtIhoJ3wj_cG2e4gW_UWdoh59AhqwIUmUaNY3.T_14evRP2Z7olYH VTF.hDQkCrmxW_5uH27.W3lqQGJ_gZ9f_6uMbgU4cTyVaCMMGMD.QMn6XM1RK80FFuu5n8kyaFCs J.jaMRS09VBo0haE76YbFJjrMIRM0tQ_kvc0rBGHg.foRoddO_jpF09c5iElspoqVeiVEg18a6tr 6dA4EU61JnwsgmkkGiIKRTLX.eKL9nkqDf0YwtjXyNJkSuwQz7p7JrfNI97RIK28noMkbRqmZ3Jw wudKIQtNFkQu1J8Zz9TOp4oLSxIwdKrnXu3Si_ckDSzV6OcTWTuI1QJMRPnOJye_kptOuxpkc5FK tYh6mQsQ0Iw4T9g-- Received: from sonic.gate.mail.ne1.yahoo.com by sonic311.consmr.mail.ne1.yahoo.com with HTTP; Thu, 29 Aug 2019 23:29:56 +0000 Received: by smtp416.mail.ne1.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID 0a952b05a9b27bc17439acbca9e87b38; Thu, 29 Aug 2019 23:29:52 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, jmorris@namei.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org Cc: casey@schaufler-ca.com, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, paul@paul-moore.com, sds@tycho.nsa.gov Subject: [PATCH v8 13/28] LSM: Use lsmblob in security_cred_getsecid Date: Thu, 29 Aug 2019 16:29:20 -0700 Message-Id: <20190829232935.7099-14-casey@schaufler-ca.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190829232935.7099-1-casey@schaufler-ca.com> References: <20190829232935.7099-1-casey@schaufler-ca.com> MIME-Version: 1.0 Sender: selinux-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: selinux@vger.kernel.org Change the security_cred_getsecid() interface to fill in a lsmblob instead of a u32 secid. The associated data elements in the audit sub-system are changed from a secid to a lsmblob to accommodate multiple possible LSM audit users. Reviewed-by: Kees Cook Reviewed-by: John Johansen Signed-off-by: Casey Schaufler --- include/linux/security.h | 2 +- kernel/audit.c | 14 +++++------- kernel/audit.h | 5 +++-- kernel/auditsc.c | 37 +++++++++++-------------------- security/integrity/ima/ima_main.c | 8 +++---- security/security.c | 12 +++++++--- 6 files changed, 36 insertions(+), 42 deletions(-) diff --git a/include/linux/security.h b/include/linux/security.h index 2d81cac418e3..d310fa3942ce 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -387,7 +387,7 @@ int security_cred_alloc_blank(struct cred *cred, gfp_t gfp); void security_cred_free(struct cred *cred); int security_prepare_creds(struct cred *new, const struct cred *old, gfp_t gfp); void security_transfer_creds(struct cred *new, const struct cred *old); -void security_cred_getsecid(const struct cred *c, u32 *secid); +void security_cred_getsecid(const struct cred *c, struct lsmblob *blob); int security_kernel_act_as(struct cred *new, struct lsmblob *blob); int security_kernel_create_files_as(struct cred *new, struct inode *inode); int security_kernel_module_request(char *kmod_name); diff --git a/kernel/audit.c b/kernel/audit.c index a0205f3c23c7..1b51e907f131 100644 --- a/kernel/audit.c +++ b/kernel/audit.c @@ -137,7 +137,7 @@ static u32 audit_backlog_wait_time = AUDIT_BACKLOG_WAIT_TIME; /* The identity of the user shutting down the audit system. */ kuid_t audit_sig_uid = INVALID_UID; pid_t audit_sig_pid = -1; -u32 audit_sig_sid = 0; +struct lsmblob audit_sig_lsm; /* Records can be lost in several ways: 0) [suppressed in audit_alloc] @@ -1429,23 +1429,21 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) } case AUDIT_SIGNAL_INFO: len = 0; - if (audit_sig_sid) { - struct lsmblob blob; - - lsmblob_init(&blob, audit_sig_sid); - err = security_secid_to_secctx(&blob, &ctx, &len); + if (lsmblob_is_set(&audit_sig_lsm)) { + err = security_secid_to_secctx(&audit_sig_lsm, &ctx, + &len); if (err) return err; } sig_data = kmalloc(sizeof(*sig_data) + len, GFP_KERNEL); if (!sig_data) { - if (audit_sig_sid) + if (lsmblob_is_set(&audit_sig_lsm)) security_release_secctx(ctx, len); return -ENOMEM; } sig_data->uid = from_kuid(&init_user_ns, audit_sig_uid); sig_data->pid = audit_sig_pid; - if (audit_sig_sid) { + if (lsmblob_is_set(&audit_sig_lsm)) { memcpy(sig_data->ctx, ctx, len); security_release_secctx(ctx, len); } diff --git a/kernel/audit.h b/kernel/audit.h index 958d5b8fc1b3..29e29c6f4afb 100644 --- a/kernel/audit.h +++ b/kernel/audit.h @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -147,7 +148,7 @@ struct audit_context { kuid_t target_auid; kuid_t target_uid; unsigned int target_sessionid; - u32 target_sid; + struct lsmblob target_lsm; char target_comm[TASK_COMM_LEN]; struct audit_tree_refs *trees, *first_trees; @@ -338,7 +339,7 @@ extern char *audit_unpack_string(void **bufp, size_t *remain, size_t len); extern pid_t audit_sig_pid; extern kuid_t audit_sig_uid; -extern u32 audit_sig_sid; +extern struct lsmblob audit_sig_lsm; extern int audit_filter(int msgtype, unsigned int listtype); diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 54797c0fc3b7..c7aa39bda5cc 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -112,7 +112,7 @@ struct audit_aux_data_pids { kuid_t target_auid[AUDIT_AUX_PIDS]; kuid_t target_uid[AUDIT_AUX_PIDS]; unsigned int target_sessionid[AUDIT_AUX_PIDS]; - u32 target_sid[AUDIT_AUX_PIDS]; + struct lsmblob target_lsm[AUDIT_AUX_PIDS]; char target_comm[AUDIT_AUX_PIDS][TASK_COMM_LEN]; int pid_count; }; @@ -938,14 +938,14 @@ static inline void audit_free_context(struct audit_context *context) } static int audit_log_pid_context(struct audit_context *context, pid_t pid, - kuid_t auid, kuid_t uid, unsigned int sessionid, - u32 sid, char *comm) + kuid_t auid, kuid_t uid, + unsigned int sessionid, + struct lsmblob *blob, char *comm) { struct audit_buffer *ab; char *ctx = NULL; u32 len; int rc = 0; - struct lsmblob blob; ab = audit_log_start(context, GFP_KERNEL, AUDIT_OBJ_PID); if (!ab) @@ -954,9 +954,8 @@ static int audit_log_pid_context(struct audit_context *context, pid_t pid, audit_log_format(ab, "opid=%d oauid=%d ouid=%d oses=%d", pid, from_kuid(&init_user_ns, auid), from_kuid(&init_user_ns, uid), sessionid); - if (sid) { - lsmblob_init(&blob, sid); - if (security_secid_to_secctx(&blob, &ctx, &len)) { + if (lsmblob_is_set(blob)) { + if (security_secid_to_secctx(blob, &ctx, &len)) { audit_log_format(ab, " obj=(none)"); rc = 1; } else { @@ -1527,7 +1526,7 @@ static void audit_log_exit(void) axs->target_auid[i], axs->target_uid[i], axs->target_sessionid[i], - axs->target_sid[i], + &axs->target_lsm[i], axs->target_comm[i])) call_panic = 1; } @@ -1536,7 +1535,7 @@ static void audit_log_exit(void) audit_log_pid_context(context, context->target_pid, context->target_auid, context->target_uid, context->target_sessionid, - context->target_sid, context->target_comm)) + &context->target_lsm, context->target_comm)) call_panic = 1; if (context->pwd.dentry && context->pwd.mnt) { @@ -1713,7 +1712,7 @@ void __audit_syscall_exit(int success, long return_code) context->aux = NULL; context->aux_pids = NULL; context->target_pid = 0; - context->target_sid = 0; + lsmblob_init(&context->target_lsm, 0); context->sockaddr_len = 0; context->type = 0; context->fds[0] = -1; @@ -2367,15 +2366,12 @@ int __audit_sockaddr(int len, void *a) void __audit_ptrace(struct task_struct *t) { struct audit_context *context = audit_context(); - struct lsmblob blob; context->target_pid = task_tgid_nr(t); context->target_auid = audit_get_loginuid(t); context->target_uid = task_uid(t); context->target_sessionid = audit_get_sessionid(t); - security_task_getsecid(t, &blob); - /* scaffolding - until target_sid is converted */ - context->target_sid = blob.secid[0]; + security_task_getsecid(t, &context->target_lsm); memcpy(context->target_comm, t->comm, TASK_COMM_LEN); } @@ -2392,7 +2388,6 @@ int audit_signal_info(int sig, struct task_struct *t) struct audit_aux_data_pids *axp; struct audit_context *ctx = audit_context(); kuid_t uid = current_uid(), auid, t_uid = task_uid(t); - struct lsmblob blob; if (auditd_test_task(t) && (sig == SIGTERM || sig == SIGHUP || @@ -2403,9 +2398,7 @@ int audit_signal_info(int sig, struct task_struct *t) audit_sig_uid = auid; else audit_sig_uid = uid; - security_task_getsecid(current, &blob); - /* scaffolding until audit_sig_sid is converted */ - audit_sig_sid = blob.secid[0]; + security_task_getsecid(current, &audit_sig_lsm); } if (!audit_signals || audit_dummy_context()) @@ -2418,9 +2411,7 @@ int audit_signal_info(int sig, struct task_struct *t) ctx->target_auid = audit_get_loginuid(t); ctx->target_uid = t_uid; ctx->target_sessionid = audit_get_sessionid(t); - security_task_getsecid(t, &blob); - /* scaffolding until target_sid is converted */ - ctx->target_sid = blob.secid[0]; + security_task_getsecid(t, &ctx->target_lsm); memcpy(ctx->target_comm, t->comm, TASK_COMM_LEN); return 0; } @@ -2441,9 +2432,7 @@ int audit_signal_info(int sig, struct task_struct *t) axp->target_auid[axp->pid_count] = audit_get_loginuid(t); axp->target_uid[axp->pid_count] = t_uid; axp->target_sessionid[axp->pid_count] = audit_get_sessionid(t); - security_task_getsecid(t, &blob); - /* scaffolding until target_sid is converted */ - axp->target_sid[axp->pid_count] = blob.secid[0]; + security_task_getsecid(t, &axp->target_lsm[axp->pid_count]); memcpy(axp->target_comm[axp->pid_count], t->comm, TASK_COMM_LEN); axp->pid_count++; diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c index fefa848cf0c7..1afb75a893af 100644 --- a/security/integrity/ima/ima_main.c +++ b/security/integrity/ima/ima_main.c @@ -363,7 +363,6 @@ int ima_file_mmap(struct file *file, unsigned long prot) int ima_bprm_check(struct linux_binprm *bprm) { int ret; - u32 secid; struct lsmblob blob; security_task_getsecid(current, &blob); @@ -373,9 +372,10 @@ int ima_bprm_check(struct linux_binprm *bprm) if (ret) return ret; - security_cred_getsecid(bprm->cred, &secid); - return process_measurement(bprm->file, bprm->cred, secid, NULL, 0, - MAY_EXEC, CREDS_CHECK); + security_cred_getsecid(bprm->cred, &blob); + /* scaffolding until process_measurement changes */ + return process_measurement(bprm->file, bprm->cred, blob.secid[0], + NULL, 0, MAY_EXEC, CREDS_CHECK); } /** diff --git a/security/security.c b/security/security.c index 745e8791b6e3..8927508b2142 100644 --- a/security/security.c +++ b/security/security.c @@ -1627,10 +1627,16 @@ void security_transfer_creds(struct cred *new, const struct cred *old) call_void_hook(cred_transfer, new, old); } -void security_cred_getsecid(const struct cred *c, u32 *secid) +void security_cred_getsecid(const struct cred *c, struct lsmblob *blob) { - *secid = 0; - call_void_hook(cred_getsecid, c, secid); + struct security_hook_list *hp; + + lsmblob_init(blob, 0); + hlist_for_each_entry(hp, &security_hook_heads.cred_getsecid, list) { + if (WARN_ON(hp->lsmid->slot < 0 || hp->lsmid->slot >= lsm_slot)) + continue; + hp->hook.cred_getsecid(c, &blob->secid[hp->lsmid->slot]); + } } EXPORT_SYMBOL(security_cred_getsecid); From patchwork Thu Aug 29 23:29:21 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 11122631 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 1C6A11395 for ; Thu, 29 Aug 2019 23:29:58 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id EEAAF2189D for ; Thu, 29 Aug 2019 23:29:57 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="ius+mIuS" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727176AbfH2X35 (ORCPT ); Thu, 29 Aug 2019 19:29:57 -0400 Received: from sonic303-28.consmr.mail.ne1.yahoo.com ([66.163.188.154]:41364 "EHLO sonic303-28.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728121AbfH2X35 (ORCPT ); Thu, 29 Aug 2019 19:29:57 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1567121394; bh=3OZ0QTMhwcTIDhDEmCMlZD0E+hS3/MR+doho0EPOFT0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=ius+mIuS7hF/YCYea2ufziWKSbFvXzl7/p5fo7On+L/m8o3sH/ehj63mwWN5aOdbDFrlHQBZsPmpOzZ/AaKBeFyuXaBv6+nc/NMDJdrKQ2KLlv34ThtAFy8fejuPpopK5EPBX8fE8byhXaGqVz/69bMnws4432UtR0YTHy5IDtbmAIZy+dRoNzYJEFHHdTul142gff0ECtQDuLsAi2sF5DKnPrD7hYXtQmF2k3xcPQqVknMMH11Haw/DJZ5Staw2o7k3JWszp15NZQTRScSF/V8yrS42YynyyqspYnI/9NI59NvrDcEmdW1ppArODKkJCHgSsnwoJ2VjA0LzKcjz3A== X-YMail-OSG: AzKRuXAVM1mE69LVQIpacoRUiKguoOWFY3Ic002XtwCzC4MDt8twRkdnKcIZXYi vST51GSF2czzkbb47WlebD..qUUYT3R1CVmnzSlTR1wVbwAktoA0mvIeQPExvoryGdm1xRm87V8A bWuJ2XxOyPd8Bm8tt_YWa9tRutqM5xv0Gb6XcqIwLi8GQVVlQ2mTZJeh2vXHrPsCfmaNlpDfQ2Ts IL5nCQV9BBGJ2RN.ZLyX4pmFv5._gcK0NyejeXcyKptNHPd5FbqWQtZD6tAWRmO7eTxVYogRbRbN Ha31q7H_MAhBan3cD0o.FRsH2iTKcksiBM8aTC7UHiKBHhbho1V02D2pPgiPM9ddrFHuDkoXu2L. jrT6J0GUQfvySdBI3GLtfas68IF43qgtZZmESOLSDW9qXC6KEW_ePQhPyrJ50_8yfuKOoeL4XczI xlshpXgB7CaSCfup8baIXxD49wOJY22ilceRniRYEfOq8vm0j48GopcjwB7h0YbHqx8PADyJoIT0 KbbiCtR.ggS0Yw4Xfq4gK2W745EpvO.bXH7pgoUu6p1kLmVW0dz_kT.kM9ztP__A2KeyUaAvahis VcKadsRGIsRgIeyYIjDNz68WqR4Xl1DBYb1tPtH3JRaTPClyc7Vbb18i3s.9ZPO5SZOa3qYSvQrU Zl8NzpWabwXRDrgMFSN2mLAYP2Q1FPwKwOgSfzV71vPlNyIaNIupal1eL.FYkjwglVLvpV0Lsbyk y9SZdVei.a8WP9T2PAbKR4xkyn0l4PhwFQIOkqAjwSZHBmMvQm3Id.ulrnTIzpy_cqC3jdRptND3 HzA9lxu5p7_ui45n1MAEuhu4kjYfk79Slke_uH2o77Pkrf_3JvA3yn.885PDjp9pJhk8dL6SLyhp Tpsdj9YLm6zUCum8fsFM.hggMHsgFKbZY2EtMtkkOWrkK4ddJHCBOtU9MYo1VD9r3vD7Yp2WRcGS DkH2I6AVFcvJZAQJBRYYt4dybOripsC70Jh.ru5feUiMli0n0TogCe4H8wfRY.e2vW6yuc7K8wwe ELyTcd4d7AaVSTaSPB3LOlJeWCMDMGJ0Zb8LtdNtJseXksfOjDVyNdP7zOxAa7eYGqnKtx5A0Fnb AxI995OUFNcwiUVQ5xSiVZNIo4BRLylVWpGf3jkaqkNgmrytF7MG7KjWw2.D5l890oiB39F1BGIh .DqGLz8.4q0uGQG114LVo3W9V2cqGcXy1C73i0JXqWGE8ewMKWtzrJjvdjYwowt3CY9rQIyp6p1z .rFXHJ0Fdn5A53Rvouxi_4NJc0kiKxvFKgDrB8qK2JRtHwE6LoOclHF9A3vAXdXRI.ScP3BB4BG2 2NSx62tmiBt4qbSs- Received: from sonic.gate.mail.ne1.yahoo.com by sonic303.consmr.mail.ne1.yahoo.com with HTTP; Thu, 29 Aug 2019 23:29:54 +0000 Received: by smtp416.mail.ne1.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID 0a952b05a9b27bc17439acbca9e87b38; Thu, 29 Aug 2019 23:29:53 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, jmorris@namei.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org Cc: casey@schaufler-ca.com, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, paul@paul-moore.com, sds@tycho.nsa.gov Subject: [PATCH v8 14/28] IMA: Change internal interfaces to use lsmblobs Date: Thu, 29 Aug 2019 16:29:21 -0700 Message-Id: <20190829232935.7099-15-casey@schaufler-ca.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190829232935.7099-1-casey@schaufler-ca.com> References: <20190829232935.7099-1-casey@schaufler-ca.com> MIME-Version: 1.0 Sender: selinux-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: selinux@vger.kernel.org The IMA interfaces ima_get_action() and ima_match_policy() call LSM functions that use lsmblobs. Change the IMA functions to pass the lsmblob to be compatible with the LSM functions. Reviewed-by: Kees Cook Reviewed-by: John Johansen Signed-off-by: Casey Schaufler --- security/integrity/ima/ima.h | 10 ++++++---- security/integrity/ima/ima_api.c | 9 +++++---- security/integrity/ima/ima_appraise.c | 4 +--- security/integrity/ima/ima_main.c | 27 +++++++++++---------------- security/integrity/ima/ima_policy.c | 12 ++++++------ 5 files changed, 29 insertions(+), 33 deletions(-) diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h index 5a337239d9e4..73b3b15dec5c 100644 --- a/security/integrity/ima/ima.h +++ b/security/integrity/ima/ima.h @@ -192,8 +192,9 @@ enum ima_hooks { }; /* LIM API function definitions */ -int ima_get_action(struct inode *inode, const struct cred *cred, u32 secid, - int mask, enum ima_hooks func, int *pcr); +int ima_get_action(struct inode *inode, const struct cred *cred, + struct lsmblob *blob, int mask, enum ima_hooks func, + int *pcr); int ima_must_measure(struct inode *inode, int mask, enum ima_hooks func); int ima_collect_measurement(struct integrity_iint_cache *iint, struct file *file, void *buf, loff_t size, @@ -213,8 +214,9 @@ void ima_free_template_entry(struct ima_template_entry *entry); const char *ima_d_path(const struct path *path, char **pathbuf, char *filename); /* IMA policy related functions */ -int ima_match_policy(struct inode *inode, const struct cred *cred, u32 secid, - enum ima_hooks func, int mask, int flags, int *pcr); +int ima_match_policy(struct inode *inode, const struct cred *cred, + struct lsmblob *blob, enum ima_hooks func, int mask, + int flags, int *pcr); void ima_init_policy(void); void ima_update_policy(void); void ima_update_policy_flag(void); diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c index c7505fb122d4..94b2a4840d81 100644 --- a/security/integrity/ima/ima_api.c +++ b/security/integrity/ima/ima_api.c @@ -159,7 +159,7 @@ void ima_add_violation(struct file *file, const unsigned char *filename, * ima_get_action - appraise & measure decision based on policy. * @inode: pointer to inode to measure * @cred: pointer to credentials structure to validate - * @secid: secid of the task being validated + * @blob: LSM data of the task being validated * @mask: contains the permission mask (MAY_READ, MAY_WRITE, MAY_EXEC, * MAY_APPEND) * @func: caller identifier @@ -175,14 +175,15 @@ void ima_add_violation(struct file *file, const unsigned char *filename, * Returns IMA_MEASURE, IMA_APPRAISE mask. * */ -int ima_get_action(struct inode *inode, const struct cred *cred, u32 secid, - int mask, enum ima_hooks func, int *pcr) +int ima_get_action(struct inode *inode, const struct cred *cred, + struct lsmblob *blob, int mask, enum ima_hooks func, + int *pcr) { int flags = IMA_MEASURE | IMA_AUDIT | IMA_APPRAISE | IMA_HASH; flags &= ima_policy_flag; - return ima_match_policy(inode, cred, secid, func, mask, flags, pcr); + return ima_match_policy(inode, cred, blob, func, mask, flags, pcr); } /* diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c index 85c7692fc4a3..3ff7aae81829 100644 --- a/security/integrity/ima/ima_appraise.c +++ b/security/integrity/ima/ima_appraise.c @@ -50,15 +50,13 @@ bool is_ima_appraise_enabled(void) */ int ima_must_appraise(struct inode *inode, int mask, enum ima_hooks func) { - u32 secid; struct lsmblob blob; if (!ima_appraise) return 0; security_task_getsecid(current, &blob); - lsmblob_secid(&blob, &secid); - return ima_match_policy(inode, current_cred(), secid, func, mask, + return ima_match_policy(inode, current_cred(), &blob, func, mask, IMA_APPRAISE | IMA_HASH, NULL); } diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c index 1afb75a893af..0588dd9a88db 100644 --- a/security/integrity/ima/ima_main.c +++ b/security/integrity/ima/ima_main.c @@ -169,8 +169,8 @@ void ima_file_free(struct file *file) } static int process_measurement(struct file *file, const struct cred *cred, - u32 secid, char *buf, loff_t size, int mask, - enum ima_hooks func) + struct lsmblob *blob, char *buf, loff_t size, + int mask, enum ima_hooks func) { struct inode *inode = file_inode(file); struct integrity_iint_cache *iint = NULL; @@ -192,7 +192,7 @@ static int process_measurement(struct file *file, const struct cred *cred, * bitmask based on the appraise/audit/measurement policy. * Included is the appraise submask. */ - action = ima_get_action(inode, cred, secid, mask, func, &pcr); + action = ima_get_action(inode, cred, blob, mask, func, &pcr); violation_check = ((func == FILE_CHECK || func == MMAP_CHECK) && (ima_policy_flag & IMA_MEASURE)); if (!action && !violation_check) @@ -339,8 +339,7 @@ int ima_file_mmap(struct file *file, unsigned long prot) if (file && (prot & PROT_EXEC)) { security_task_getsecid(current, &blob); - /* scaffolding - until process_measurement changes */ - return process_measurement(file, current_cred(), blob.secid[0], + return process_measurement(file, current_cred(), &blob, NULL, 0, MAY_EXEC, MMAP_CHECK); } @@ -366,16 +365,14 @@ int ima_bprm_check(struct linux_binprm *bprm) struct lsmblob blob; security_task_getsecid(current, &blob); - /* scaffolding until process_measurement changes */ - ret = process_measurement(bprm->file, current_cred(), blob.secid[0], - NULL, 0, MAY_EXEC, BPRM_CHECK); + ret = process_measurement(bprm->file, current_cred(), &blob, NULL, 0, + MAY_EXEC, BPRM_CHECK); if (ret) return ret; security_cred_getsecid(bprm->cred, &blob); - /* scaffolding until process_measurement changes */ - return process_measurement(bprm->file, bprm->cred, blob.secid[0], - NULL, 0, MAY_EXEC, CREDS_CHECK); + return process_measurement(bprm->file, bprm->cred, &blob, NULL, 0, + MAY_EXEC, CREDS_CHECK); } /** @@ -393,8 +390,7 @@ int ima_file_check(struct file *file, int mask) struct lsmblob blob; security_task_getsecid(current, &blob); - /* scaffolding until process_measurement changes */ - return process_measurement(file, current_cred(), blob.secid[0], NULL, 0, + return process_measurement(file, current_cred(), &blob, NULL, 0, mask & (MAY_READ | MAY_WRITE | MAY_EXEC | MAY_APPEND), FILE_CHECK); } @@ -526,9 +522,8 @@ int ima_post_read_file(struct file *file, void *buf, loff_t size, func = read_idmap[read_id] ?: FILE_CHECK; security_task_getsecid(current, &blob); - /* scaffolding until process_measurement changes */ - return process_measurement(file, current_cred(), blob.secid[0], buf, - size, MAY_READ, func); + return process_measurement(file, current_cred(), &blob, buf, size, + MAY_READ, func); } /** diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c index 92ee3d984c73..dbad256aa7b4 100644 --- a/security/integrity/ima/ima_policy.c +++ b/security/integrity/ima/ima_policy.c @@ -286,7 +286,7 @@ static void ima_lsm_update_rules(void) * Returns true on rule match, false on failure. */ static bool ima_match_rules(struct ima_rule_entry *rule, struct inode *inode, - const struct cred *cred, u32 secid, + const struct cred *cred, struct lsmblob *blob, enum ima_hooks func, int mask) { int i; @@ -345,7 +345,6 @@ static bool ima_match_rules(struct ima_rule_entry *rule, struct inode *inode, case LSM_SUBJ_USER: case LSM_SUBJ_ROLE: case LSM_SUBJ_TYPE: - lsmblob_init(&blob, secid); rc = security_filter_rule_match(&blob, rule->lsm[i].type, Audit_equal, @@ -394,7 +393,7 @@ static int get_subaction(struct ima_rule_entry *rule, enum ima_hooks func) * @inode: pointer to an inode for which the policy decision is being made * @cred: pointer to a credentials structure for which the policy decision is * being made - * @secid: LSM secid of the task to be validated + * @blob: LSM data of the task to be validated * @func: IMA hook identifier * @mask: requested action (MAY_READ | MAY_WRITE | MAY_APPEND | MAY_EXEC) * @pcr: set the pcr to extend @@ -406,8 +405,9 @@ static int get_subaction(struct ima_rule_entry *rule, enum ima_hooks func) * list when walking it. Reads are many orders of magnitude more numerous * than writes so ima_match_policy() is classical RCU candidate. */ -int ima_match_policy(struct inode *inode, const struct cred *cred, u32 secid, - enum ima_hooks func, int mask, int flags, int *pcr) +int ima_match_policy(struct inode *inode, const struct cred *cred, + struct lsmblob *blob, enum ima_hooks func, int mask, + int flags, int *pcr) { struct ima_rule_entry *entry; int action = 0, actmask = flags | (flags << 1); @@ -418,7 +418,7 @@ int ima_match_policy(struct inode *inode, const struct cred *cred, u32 secid, if (!(entry->action & actmask)) continue; - if (!ima_match_rules(entry, inode, cred, secid, func, mask)) + if (!ima_match_rules(entry, inode, cred, blob, func, mask)) continue; action |= entry->flags & IMA_ACTION_FLAGS; From patchwork Thu Aug 29 23:29:22 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 11122639 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 5E802112C for ; Thu, 29 Aug 2019 23:30:06 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 32AE72173E for ; Thu, 29 Aug 2019 23:30:06 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="VzGpQPbZ" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728121AbfH2XaG (ORCPT ); Thu, 29 Aug 2019 19:30:06 -0400 Received: from sonic311-23.consmr.mail.bf2.yahoo.com ([74.6.131.197]:41822 "EHLO sonic311-23.consmr.mail.bf2.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728129AbfH2XaF (ORCPT ); Thu, 29 Aug 2019 19:30:05 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1567121402; bh=LOGjl+xuGgyPyNl5cHaq2z1YN7D7LvdGIufbOcZuT70=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=VzGpQPbZckov/cDWtpBwlqtB8+MaWYkq1WzKO0RXwfED1uihSI3bNjkm6Rhh+APq5db+nzYT37YwoGe0tiXde0B/gnlNzlc0O47wtQMkNLuZ16XqCsL+rIUffPC5F+mKSXwABpKtlVEdTtk4FMblLup9BU7D+zA4MdaH66vYfysyHrzBPLKAD794lzaSaTNtlgsRf2U+lrJtm3aZL/VWvXddS5WqDMXHNdU8fON0JuUU6y7uQkJ3mhUDvBHdvYnlQIriB1BlduynfRtBbCMl/XK8Jj5fKw47e7//Wi5Jq94xw2vAUdk705bWlG42ymKowi7asoZGH/2qbazEAtc3/g== X-YMail-OSG: OpNHuvsVM1kWBvsi0roMFm8Wqt5D2kcg72jhsrhfemHWYcv0yj.B_sQkmWYeGWV bxsyQpXnwop7_U3tqb28bxMfhcFxU8jZZRaoC_0x8u03pjoEYJ0hAf_28CVu3JpslwbPMmgpvlf9 1ldMGqDz87WbqWDgLBJn5FgviTi_rfC6nZ9AKbiEvv2NXH2wdVhxwf5s26hLM.sn5TTebRURGBBP lVRGuWPleJaLZSSblYEigFiaJjuwRmnq0bG9XFI.linerdaPPdnDHuYGBeuhDU9HOXMLInppL04T AWZrAMxnO2yzjYyG6NEwKmWm75bkbpFlUzlAHc3jUOG_Kc4ovLPAHeFIAs5GwN1ckj35mJXzFqoC 0M0HfwJr3WWg1rPhnz3V2.genpCNBDumFRA5hY0Png8YBIfG3jN1t_VPx3ry053AM5kff0WUDMnC MPLaz8eVZ8vUdINE_rXYkn6fKBzepiZosF673.FqeK2A2V4jc8pUSCMC_5cs_RqIugnvYOFLQXvO zIdNI_K3aMC9HZ2StPj1KYk1ndn.rsGoXAaC0BtnjEYlV_D8SLYpdMbph7Bu8Db0MKWKOF5WWryJ odzSNJ83jZXi5LbMCXy5eMRp2kQE8VYEQLrsTXOMiQFgGfAB3_UnyrGDWANQbb.3VdsbPVKbatWn C0l2_MF0MHQktWwdH.xmoUgJ._BiOyVvKSS8dPtnE51o3XAGJM40Mb_zX8J3IOk1YruiExmD1dlY UJEP7p6t1VP7rmgdQ23cAW764ELjE.fgN57M0t.AHdEdfRCFIZFFgDo0_l7W7dVIuqLZkFIWWCVt 9GXbNSi8044fQHT9RraPqI4GbjBxg6tSKwwBs0FO6nLv8x9XGkxK0qHk5vdiPs.D95D.Qn6sr6U_ 2xegc1j0KPgeUoKfY3XcIWAWUTEAgAeAwZKOBHXC4W7K6iG2dXKbqPs6KT8nsToykApp6FkMhGfb itVDWDPNEZNWYJgQ7JgHQ2K6dYUeRNTJ6atsZkFeah8jiZvYvv.xK7CsVqC6sTcNIB7LcwPk.BED cCW1VWFhKamd.q3zZZbVPWF65F.3cEXbK26sIYGeXDmgI5uCNW7J6GvB.WFVWIR1iLUQ42zUJBmi EqECoaiFpgAhsNqd_EHaFJOpeT_U5KlrvkdGmAYLKFhynwu2G0Beqt._JJcVODhcL.lU3IHvUiiH Yd2l.0Xdz3Ht1UH8ylEO9enY5_HL48WvNPgLXpI9qa_ux8c6tRKjdN385AhNLAjaBOCuTmNPnTPs I.LrKYh9u59ORP1n.33RNizayXE1wKnPQOPnyYoPLW8kxjLMejp8arY0A61IwugT05nSH9AiWHZy 5MQ-- Received: from sonic.gate.mail.ne1.yahoo.com by sonic311.consmr.mail.bf2.yahoo.com with HTTP; Thu, 29 Aug 2019 23:30:02 +0000 Received: by smtp408.mail.bf1.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID 2d799b9799b92d4529ae6bd2b9fbf9fb; Thu, 29 Aug 2019 23:29:59 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, jmorris@namei.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org Cc: casey@schaufler-ca.com, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, paul@paul-moore.com, sds@tycho.nsa.gov Subject: [PATCH v8 15/28] LSM: Specify which LSM to display Date: Thu, 29 Aug 2019 16:29:22 -0700 Message-Id: <20190829232935.7099-16-casey@schaufler-ca.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190829232935.7099-1-casey@schaufler-ca.com> References: <20190829232935.7099-1-casey@schaufler-ca.com> MIME-Version: 1.0 Sender: selinux-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: selinux@vger.kernel.org Create a new entry "display" in /proc/.../attr for controlling which LSM security information is displayed for a process. The name of an active LSM that supplies hooks for human readable data may be written to "display" to set the value. This requires CAP_MAC_ADMIN privilege. The name of the LSM currently in use can be read from "display". At this point there can only be one LSM capable of display active. A helper function lsm_task_display() is provided to get the display slot for a task_struct. Note that procfs restricts writes in the attr directory to 'self'. Signed-off-by: Casey Schaufler --- fs/proc/base.c | 1 + include/linux/lsm_hooks.h | 15 ++++ security/security.c | 148 +++++++++++++++++++++++++++++++++----- 3 files changed, 147 insertions(+), 17 deletions(-) diff --git a/fs/proc/base.c b/fs/proc/base.c index ddef482f1334..7bf70e041315 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -2618,6 +2618,7 @@ static const struct pid_entry attr_dir_stuff[] = { ATTR(NULL, "fscreate", 0666), ATTR(NULL, "keycreate", 0666), ATTR(NULL, "sockcreate", 0666), + ATTR(NULL, "display", 0666), #ifdef CONFIG_SECURITY_SMACK DIR("smack", 0555, proc_smack_attr_dir_inode_ops, proc_smack_attr_dir_ops), diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h index fe1fb7a69ee5..33e5ab4af9f8 100644 --- a/include/linux/lsm_hooks.h +++ b/include/linux/lsm_hooks.h @@ -2134,4 +2134,19 @@ static inline void security_delete_hooks(struct security_hook_list *hooks, extern int lsm_inode_alloc(struct inode *inode); +/** + * lsm_task_display - the "display LSM for this task + * @task: The task to report on + * + * Returns the task's display LSM slot. + */ +static inline int lsm_task_display(struct task_struct *task) +{ + int *display = task->security; + + if (display) + return *display; + return LSMBLOB_INVALID; +} + #endif /* ! __LINUX_LSM_HOOKS_H */ diff --git a/security/security.c b/security/security.c index 8927508b2142..c3c9bd88b7af 100644 --- a/security/security.c +++ b/security/security.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -46,7 +47,14 @@ static struct kmem_cache *lsm_file_cache; static struct kmem_cache *lsm_inode_cache; char *lsm_names; -static struct lsm_blob_sizes blob_sizes __lsm_ro_after_init; + +/* + * The task blob includes the "display" slot used for + * chosing which module presents contexts. + */ +static struct lsm_blob_sizes blob_sizes __lsm_ro_after_init = { + .lbs_task = sizeof(int), +}; /* Boot-time LSM user choice */ static __initdata const char *chosen_lsm_order; @@ -423,8 +431,10 @@ static int lsm_append(const char *new, char **result) /* * Current index to use while initializing the lsmblob secid list. + * Pointers to the LSM id structures for local use. */ static int lsm_slot __lsm_ro_after_init; +static struct lsm_id *lsm_slotlist[LSMBLOB_ENTRIES]; /** * security_add_hooks - Add a modules hooks to the hook lists. @@ -444,6 +454,7 @@ void __init security_add_hooks(struct security_hook_list *hooks, int count, if (lsmid->slot == LSMBLOB_NEEDED) { if (lsm_slot >= LSMBLOB_ENTRIES) panic("%s Too many LSMs registered.\n", __func__); + lsm_slotlist[lsm_slot] = lsmid; lsmid->slot = lsm_slot++; init_debug("%s assigned lsmblob slot %d\n", lsmid->lsm, lsmid->slot); @@ -564,6 +575,8 @@ int lsm_inode_alloc(struct inode *inode) */ static int lsm_task_alloc(struct task_struct *task) { + int *display; + if (blob_sizes.lbs_task == 0) { task->security = NULL; return 0; @@ -572,6 +585,15 @@ static int lsm_task_alloc(struct task_struct *task) task->security = kzalloc(blob_sizes.lbs_task, GFP_KERNEL); if (task->security == NULL) return -ENOMEM; + + /* + * The start of the task blob contains the "display" LSM slot number. + * Start with it set to the invalid slot number, indicating that the + * default first registered LSM be displayed. + */ + display = task->security; + *display = LSMBLOB_INVALID; + return 0; } @@ -1563,14 +1585,26 @@ int security_file_open(struct file *file) int security_task_alloc(struct task_struct *task, unsigned long clone_flags) { + int *odisplay = current->security; + int *ndisplay; int rc = lsm_task_alloc(task); - if (rc) + if (unlikely(rc)) return rc; + rc = call_int_hook(task_alloc, 0, task, clone_flags); - if (unlikely(rc)) + if (unlikely(rc)) { security_task_free(task); - return rc; + return rc; + } + + if (odisplay) { + ndisplay = task->security; + if (ndisplay) + *ndisplay = *odisplay; + } + + return 0; } void security_task_free(struct task_struct *task) @@ -1967,23 +2001,89 @@ int security_getprocattr(struct task_struct *p, const char *lsm, char *name, char **value) { struct security_hook_list *hp; + int display = lsm_task_display(current); + int slot = 0; + + if (!strcmp(name, "display")) { + /* + * lsm_slot will be 0 if there are no displaying modules. + */ + if (lsm_slot == 0) + return -EINVAL; + if (display != LSMBLOB_INVALID) + slot = display; + *value = kstrdup(lsm_slotlist[slot]->lsm, GFP_KERNEL); + if (*value) + return strlen(*value); + return -ENOMEM; + } hlist_for_each_entry(hp, &security_hook_heads.getprocattr, list) { if (lsm != NULL && strcmp(lsm, hp->lsmid->lsm)) continue; + if (lsm == NULL && display != LSMBLOB_INVALID && + display != hp->lsmid->slot) + continue; return hp->hook.getprocattr(p, name, value); } return -EINVAL; } +/** + * security_setprocattr - Set process attributes via /proc + * @lsm: name of module involved, or NULL + * @name: name of the attribute + * @value: value to set the attribute to + * @size: size of the value + * + * Set the process attribute for the specified security module + * to the specified value. Note that this can only be used to set + * the process attributes for the current, or "self" process. + * The /proc code has already done this check. + * + * Returns 0 on success, an appropriate code otherwise. + */ int security_setprocattr(const char *lsm, const char *name, void *value, size_t size) { struct security_hook_list *hp; + char *term; + char *cp; + int *display = current->security; + int rc = -EINVAL; + int slot = 0; + + if (!strcmp(name, "display")) { + if (!capable(CAP_MAC_ADMIN)) + return -EPERM; + /* + * lsm_slot will be 0 if there are no displaying modules. + */ + if (lsm_slot == 0 || size == 0) + return -EINVAL; + term = kmemdup_nul(value, size, GFP_KERNEL); + if (term == NULL) + return -ENOMEM; + + cp = strsep(&term, " \n"); + + for (slot = 0; slot < lsm_slot; slot++) + if (!strcmp(cp, lsm_slotlist[slot]->lsm)) { + *display = lsm_slotlist[slot]->slot; + rc = size; + break; + } + + kfree(cp); + return rc; + } hlist_for_each_entry(hp, &security_hook_heads.setprocattr, list) { if (lsm != NULL && strcmp(lsm, hp->lsmid->lsm)) continue; + if (lsm == NULL && *display != LSMBLOB_INVALID && + *display != hp->lsmid->slot) + continue; return hp->hook.setprocattr(name, value, size); } return -EINVAL; @@ -2003,15 +2103,15 @@ EXPORT_SYMBOL(security_ismaclabel); int security_secid_to_secctx(struct lsmblob *blob, char **secdata, u32 *seclen) { struct security_hook_list *hp; - int rc; + int display = lsm_task_display(current); hlist_for_each_entry(hp, &security_hook_heads.secid_to_secctx, list) { if (WARN_ON(hp->lsmid->slot < 0 || hp->lsmid->slot >= lsm_slot)) continue; - rc = hp->hook.secid_to_secctx(blob->secid[hp->lsmid->slot], - secdata, seclen); - if (rc != 0) - return rc; + if (display == LSMBLOB_INVALID || display == hp->lsmid->slot) + return hp->hook.secid_to_secctx( + blob->secid[hp->lsmid->slot], + secdata, seclen); } return 0; } @@ -2021,16 +2121,15 @@ int security_secctx_to_secid(const char *secdata, u32 seclen, struct lsmblob *blob) { struct security_hook_list *hp; - int rc; + int display = lsm_task_display(current); lsmblob_init(blob, 0); hlist_for_each_entry(hp, &security_hook_heads.secctx_to_secid, list) { if (WARN_ON(hp->lsmid->slot < 0 || hp->lsmid->slot >= lsm_slot)) continue; - rc = hp->hook.secctx_to_secid(secdata, seclen, - &blob->secid[hp->lsmid->slot]); - if (rc != 0) - return rc; + if (display == LSMBLOB_INVALID || display == hp->lsmid->slot) + return hp->hook.secctx_to_secid(secdata, seclen, + &blob->secid[hp->lsmid->slot]); } return 0; } @@ -2038,7 +2137,15 @@ EXPORT_SYMBOL(security_secctx_to_secid); void security_release_secctx(char *secdata, u32 seclen) { - call_void_hook(release_secctx, secdata, seclen); + struct security_hook_list *hp; + int *display = current->security; + + hlist_for_each_entry(hp, &security_hook_heads.release_secctx, list) + if (display == NULL || *display == LSMBLOB_INVALID || + *display == hp->lsmid->slot) { + hp->hook.release_secctx(secdata, seclen); + return; + } } EXPORT_SYMBOL(security_release_secctx); @@ -2163,8 +2270,15 @@ EXPORT_SYMBOL(security_sock_rcv_skb); int security_socket_getpeersec_stream(struct socket *sock, char __user *optval, int __user *optlen, unsigned len) { - return call_int_hook(socket_getpeersec_stream, -ENOPROTOOPT, sock, - optval, optlen, len); + int display = lsm_task_display(current); + struct security_hook_list *hp; + + hlist_for_each_entry(hp, &security_hook_heads.socket_getpeersec_stream, + list) + if (display == LSMBLOB_INVALID || display == hp->lsmid->slot) + return hp->hook.socket_getpeersec_stream(sock, optval, + optlen, len); + return -ENOPROTOOPT; } int security_socket_getpeersec_dgram(struct socket *sock, struct sk_buff *skb, From patchwork Thu Aug 29 23:29:23 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 11122645 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id D0E36112C for ; Thu, 29 Aug 2019 23:30:10 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id A3A142173E for ; Thu, 29 Aug 2019 23:30:10 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="U0ecKHJC" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728146AbfH2XaK (ORCPT ); Thu, 29 Aug 2019 19:30:10 -0400 Received: from sonic313-22.consmr.mail.bf2.yahoo.com ([74.6.133.196]:38836 "EHLO sonic313-22.consmr.mail.bf2.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728192AbfH2XaJ (ORCPT ); Thu, 29 Aug 2019 19:30:09 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1567121406; bh=q74Y9lwvEHiKSpnOTSQOUt4FLP+KYuL7uxPpMATvKJU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=U0ecKHJC+x5mpgryE+cgccJjjEA129Z9JsAvPzOqoDdug4cVgCjSzpsRUlilthPqw/k8dklNvF2zJGcPJTDcG4u1mes5Rrm3EdibeLCmXeoDU8xGguE4R4twp+/enAR64Z5KA38K98pbLBClIZKfGt0jnWL/Njlbk0W4XXblNEMS7nmQsLtzVRneGTpBgUSDqOs/ofI5j0tlJonC+CIMNH/iqI0CwoUutnUANmseqiKN5+BqsdWdBUfXHR5m2EJpLvNGrpeaOwPqmsaZLjnJiC8NA/sXsPlznwCrlFAg6nuEZ4dhl5yJRMelVYvX8YspcFilqE5y/YSS2FhV02XFTg== X-YMail-OSG: 7Z4Cf7AVM1kecCs7oMwVzIhngMxTyQMdWNaeKwseTiZ5hIZtyxKTsbpy7a_zZgZ K2xg91TE4lGe.XZCnm5ahfQdBUDJXuUrHePHQvE6F_fpzWRMp2onCloZYLpzyyzlDwd_VQqYOdR9 hwrQddLm9wupGevmuiSfo4Ls4Y2U0DpwCilFfoQoeG.NuPCENrjfFVF.LGhL78HhIhT01DaaxNF3 _7DqTkulpkRjgmwElCYKuqBYc5QIYqZ6oCPIT7FbyjLiy_.LcdRGh5M4xSrNyILD5WR9bYQq5CRU t6bln_WodWvuJReTaqDfTmi9LlXzoSf79MHqRTl1qmhtSTV0cwjktzuiv3prc7x8bC43Q5n4VNZY 3nFBfDItf.FXJwGi_FPEBMzVDK2FwVG_zOSMx3vMuG18QNwRCWyEqduAbPgOR4S4eJcmizgUpxiR eY8.Cg.FAd17Y1YxwaPuqCUIgWZ3.Io6UCGnOsY0fpz8Rf1_i1oXiYUnSRpQRBPxD9R5NzVngvXz bgPTAzY8z6FdCnPX5lqThSXWh7atlLVDfA4E5gTYZZ5PULyBHD99KWtiJ3bXOLmdKluUFALYABZm PjvbhwD3Lv3UK0jU5NXgwaGEm8Dw16oAUWseyjTh7p6BiM3b9sU5x9k7ljhk38Gkyp6wn0Yxf4iA 8dIKyxtfOOJ2pZ.nL1cCeJMoPa213BJjUqdfolcp8tqsMfzXkmNUKjNnWDALYodDN35cvofudpbQ P_Yj2lvZjGjRSoTvnbK3cpoNh.vcgVpz7pDU1xg8HO2c4QxpKZB6l0cj6.3TrNXYibtUGwUXQfxh HftdNfyncGKct8jxj8ZarAUsFfGEF8RZ.dFRh5V2Fp6i08oZI6KcnxbrjEIIFlr0TtnrOBdRw1FT Q3Oqn8sSAg5.36FHFqG.ycRKZnm3aSJWdN0X7ETCEkUip8TQV.5Sbx1jd_lyl_uEynQ1Bq3C7kYc 0z86Mje3NjGbfCiPLqBb.1hDRdZysEtlw5K.Azy2vHizg4JYp9ex..9J4XCVromKOn5boM2xTv0c T05.UxQ6a.ZHSYE1ik8NarcdMYXKjRHZmGsP0Z3sRuQr0ppnIPtnLAEDytMJ.jcIGBvmst5nN9YN WiMC_aSlWKHPlDebE6YlBgTv4oOCArVwTA68aBpHS2T5km1toAh0dyRe8PR0tFewIWYTSS8xXBD9 zC2oW2PZz7Q0t7Po.YtMKMKlmcXC59Ifzzojv6lB1yWwy6DrSv8_fJlD54X92YXQlRsfalX4Qgym 1AF.kuGp1v8ehvJSVctfvS71noAYUo7.3iyrxLLThT3hyiLbAHydCuXW8yowJCD4J367n73ge1UZ JM205Xj6v6g-- Received: from sonic.gate.mail.ne1.yahoo.com by sonic313.consmr.mail.bf2.yahoo.com with HTTP; Thu, 29 Aug 2019 23:30:06 +0000 Received: by smtp408.mail.bf1.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID 2d799b9799b92d4529ae6bd2b9fbf9fb; Thu, 29 Aug 2019 23:30:02 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, jmorris@namei.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org Cc: casey@schaufler-ca.com, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, paul@paul-moore.com, sds@tycho.nsa.gov Subject: [PATCH v8 16/28] LSM: Ensure the correct LSM context releaser Date: Thu, 29 Aug 2019 16:29:23 -0700 Message-Id: <20190829232935.7099-17-casey@schaufler-ca.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190829232935.7099-1-casey@schaufler-ca.com> References: <20190829232935.7099-1-casey@schaufler-ca.com> MIME-Version: 1.0 Sender: selinux-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: selinux@vger.kernel.org Add a new lsmcontext data structure to hold all the information about a "security context", including the string, its size and which LSM allocated the string. The allocation information is necessary because LSMs have different policies regarding the lifecycle of these strings. SELinux allocates and destroys them on each use, whereas Smack provides a pointer to an entry in a list that never goes away. Reviewed-by: Kees Cook Reviewed-by: John Johansen Signed-off-by: Casey Schaufler --- drivers/android/binder.c | 10 +++++-- fs/kernfs/dir.c | 10 +++++-- fs/kernfs/inode.c | 7 +++-- fs/nfs/nfs4proc.c | 8 +++-- fs/nfsd/nfs4xdr.c | 7 +++-- include/linux/security.h | 39 +++++++++++++++++++++++-- include/net/scm.h | 5 +++- kernel/audit.c | 14 ++++++--- kernel/auditsc.c | 12 ++++++-- net/ipv4/ip_sockglue.c | 4 ++- net/netfilter/nf_conntrack_netlink.c | 4 ++- net/netfilter/nf_conntrack_standalone.c | 4 ++- net/netfilter/nfnetlink_queue.c | 13 ++++++--- net/netlabel/netlabel_unlabeled.c | 19 +++++++++--- net/netlabel/netlabel_user.c | 4 ++- security/security.c | 18 ++++++++---- security/smack/smack_lsm.c | 14 ++++++--- 17 files changed, 148 insertions(+), 44 deletions(-) diff --git a/drivers/android/binder.c b/drivers/android/binder.c index 144ac4f1c24f..89e574be34cc 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -2876,6 +2876,7 @@ static void binder_transaction(struct binder_proc *proc, int t_debug_id = atomic_inc_return(&binder_last_id); char *secctx = NULL; u32 secctx_sz = 0; + struct lsmcontext scaff; /* scaffolding */ e = binder_transaction_log_add(&binder_transaction_log); e->debug_id = t_debug_id; @@ -3158,7 +3159,8 @@ static void binder_transaction(struct binder_proc *proc, binder_alloc_copy_to_buffer(&target_proc->alloc, t->buffer, buf_offset, secctx, secctx_sz); - security_release_secctx(secctx, secctx_sz); + lsmcontext_init(&scaff, secctx, secctx_sz, 0); + security_release_secctx(&scaff); secctx = NULL; } t->buffer->debug_id = t->debug_id; @@ -3479,8 +3481,10 @@ static void binder_transaction(struct binder_proc *proc, t->buffer->transaction = NULL; binder_alloc_free_buf(&target_proc->alloc, t->buffer); err_binder_alloc_buf_failed: - if (secctx) - security_release_secctx(secctx, secctx_sz); + if (secctx) { + lsmcontext_init(&scaff, secctx, secctx_sz, 0); + security_release_secctx(&scaff); + } err_get_secctx_failed: kfree(tcomplete); binder_stats_deleted(BINDER_STAT_TRANSACTION_COMPLETE); diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c index b84d635567d3..c8362b6d556e 100644 --- a/fs/kernfs/dir.c +++ b/fs/kernfs/dir.c @@ -532,9 +532,13 @@ void kernfs_put(struct kernfs_node *kn) kfree_const(kn->name); if (kn->iattr) { - if (kn->iattr->ia_secdata) - security_release_secctx(kn->iattr->ia_secdata, - kn->iattr->ia_secdata_len); + struct lsmcontext scaff; /* scaffolding */ + + if (kn->iattr->ia_secdata) { + lsmcontext_init(&scaff, kn->iattr->ia_secdata, + kn->iattr->ia_secdata_len, 0); + security_release_secctx(&scaff); + } simple_xattrs_free(&kn->iattr->xattrs); kmem_cache_free(kernfs_iattrs_cache, kn->iattr); } diff --git a/fs/kernfs/inode.c b/fs/kernfs/inode.c index 0c1fd945ce42..02cde9dac5ee 100644 --- a/fs/kernfs/inode.c +++ b/fs/kernfs/inode.c @@ -349,6 +349,7 @@ static int kernfs_security_xattr_set(const struct xattr_handler *handler, { struct kernfs_node *kn = inode->i_private; struct kernfs_iattrs *attrs; + struct lsmcontext context; void *secdata; u32 secdata_len = 0; int error; @@ -368,8 +369,10 @@ static int kernfs_security_xattr_set(const struct xattr_handler *handler, error = kernfs_node_setsecdata(attrs, &secdata, &secdata_len); mutex_unlock(&kernfs_mutex); - if (secdata) - security_release_secctx(secdata, secdata_len); + if (secdata) { + lsmcontext_init(&context, secdata, secdata_len, 0); + security_release_secctx(&context); + } return error; } diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 4dbb0ee23432..af1c0db29c39 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -131,8 +131,12 @@ nfs4_label_init_security(struct inode *dir, struct dentry *dentry, static inline void nfs4_label_release_security(struct nfs4_label *label) { - if (label) - security_release_secctx(label->label, label->len); + struct lsmcontext scaff; /* scaffolding */ + + if (label) { + lsmcontext_init(&scaff, label->label, label->len, 0); + security_release_secctx(&scaff); + } } static inline u32 *nfs4_bitmask(struct nfs_server *server, struct nfs4_label *label) { diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 3de42a729093..bb3db033e144 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -2420,6 +2420,7 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp, __be32 status; int err; struct nfs4_acl *acl = NULL; + struct lsmcontext scaff; /* scaffolding */ void *context = NULL; int contextlen; bool contextsupport = false; @@ -2919,8 +2920,10 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp, out: #ifdef CONFIG_NFSD_V4_SECURITY_LABEL - if (context) - security_release_secctx(context, contextlen); + if (context) { + lsmcontext_init(&scaff, context, contextlen, 0); /*scaffolding*/ + security_release_secctx(&scaff); + } #endif /* CONFIG_NFSD_V4_SECURITY_LABEL */ kfree(acl); if (tempfh) { diff --git a/include/linux/security.h b/include/linux/security.h index d310fa3942ce..046012a7255f 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -76,6 +76,41 @@ enum lsm_event { LSM_POLICY_CHANGE, }; +/* + * A "security context" is the text representation of + * the information used by LSMs. + * This structure contains the string, its length, and which LSM + * it is useful for. + */ +struct lsmcontext { + char *context; /* Provided by the module */ + u32 len; + int slot; /* Identifies the module */ +}; + +/** + * lsmcontext_init - initialize an lsmcontext structure. + * @cp: Pointer to the context to initialize + * @context: Initial context, or NULL + * @size: Size of context, or 0 + * @slot: Which LSM provided the context + * + * Fill in the lsmcontext from the provided information. + * This is a scaffolding function that will be removed when + * lsmcontext integration is complete. + */ +static inline void lsmcontext_init(struct lsmcontext *cp, char *context, + u32 size, int slot) +{ + cp->slot = slot; + cp->context = context; + + if (context == NULL || size == 0) + cp->len = 0; + else + cp->len = strlen(context); +} + /* * Data exported by the security modules * @@ -449,7 +484,7 @@ int security_ismaclabel(const char *name); int security_secid_to_secctx(struct lsmblob *blob, char **secdata, u32 *seclen); int security_secctx_to_secid(const char *secdata, u32 seclen, struct lsmblob *blob); -void security_release_secctx(char *secdata, u32 seclen); +void security_release_secctx(struct lsmcontext *cp); void security_inode_invalidate_secctx(struct inode *inode); int security_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen); @@ -1240,7 +1275,7 @@ static inline int security_secctx_to_secid(const char *secdata, return -EOPNOTSUPP; } -static inline void security_release_secctx(char *secdata, u32 seclen) +static inline void security_release_secctx(struct lsmcontext *cp) { } diff --git a/include/net/scm.h b/include/net/scm.h index 31ae605fcc0a..30ba801c91bd 100644 --- a/include/net/scm.h +++ b/include/net/scm.h @@ -92,6 +92,7 @@ static __inline__ int scm_send(struct socket *sock, struct msghdr *msg, #ifdef CONFIG_SECURITY_NETWORK static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm) { + struct lsmcontext context; char *secdata; u32 seclen; int err; @@ -102,7 +103,9 @@ static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct sc if (!err) { put_cmsg(msg, SOL_SOCKET, SCM_SECURITY, seclen, secdata); - security_release_secctx(secdata, seclen); + /*scaffolding*/ + lsmcontext_init(&context, secdata, seclen, 0); + security_release_secctx(&context); } } } diff --git a/kernel/audit.c b/kernel/audit.c index 1b51e907f131..f844a2a642e6 100644 --- a/kernel/audit.c +++ b/kernel/audit.c @@ -1193,6 +1193,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) struct audit_sig_info *sig_data; char *ctx = NULL; u32 len; + struct lsmcontext scaff; /* scaffolding */ err = audit_netlink_ok(skb, msg_type); if (err) @@ -1437,15 +1438,18 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) } sig_data = kmalloc(sizeof(*sig_data) + len, GFP_KERNEL); if (!sig_data) { - if (lsmblob_is_set(&audit_sig_lsm)) - security_release_secctx(ctx, len); + if (lsmblob_is_set(&audit_sig_lsm)) { + lsmcontext_init(&scaff, ctx, len, 0); + security_release_secctx(&scaff); + } return -ENOMEM; } sig_data->uid = from_kuid(&init_user_ns, audit_sig_uid); sig_data->pid = audit_sig_pid; if (lsmblob_is_set(&audit_sig_lsm)) { memcpy(sig_data->ctx, ctx, len); - security_release_secctx(ctx, len); + lsmcontext_init(&scaff, ctx, len, 0); + security_release_secctx(&scaff); } audit_send_reply(skb, seq, AUDIT_SIGNAL_INFO, 0, 0, sig_data, sizeof(*sig_data) + len); @@ -2074,6 +2078,7 @@ int audit_log_task_context(struct audit_buffer *ab) unsigned len; int error; struct lsmblob blob; + struct lsmcontext scaff; /* scaffolding */ security_task_getsecid(current, &blob); if (!lsmblob_is_set(&blob)) @@ -2087,7 +2092,8 @@ int audit_log_task_context(struct audit_buffer *ab) } audit_log_format(ab, " subj=%s", ctx); - security_release_secctx(ctx, len); + lsmcontext_init(&scaff, ctx, len, 0); + security_release_secctx(&scaff); return 0; error_path: diff --git a/kernel/auditsc.c b/kernel/auditsc.c index c7aa39bda5cc..9fab0e7d90c3 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -943,6 +943,7 @@ static int audit_log_pid_context(struct audit_context *context, pid_t pid, struct lsmblob *blob, char *comm) { struct audit_buffer *ab; + struct lsmcontext lsmcxt; char *ctx = NULL; u32 len; int rc = 0; @@ -960,7 +961,8 @@ static int audit_log_pid_context(struct audit_context *context, pid_t pid, rc = 1; } else { audit_log_format(ab, " obj=%s", ctx); - security_release_secctx(ctx, len); + lsmcontext_init(&lsmcxt, ctx, len, 0); /*scaffolding*/ + security_release_secctx(&lsmcxt); } } audit_log_format(ab, " ocomm="); @@ -1172,6 +1174,7 @@ static void audit_log_fcaps(struct audit_buffer *ab, struct audit_names *name) static void show_special(struct audit_context *context, int *call_panic) { + struct lsmcontext lsmcxt; struct audit_buffer *ab; int i; @@ -1205,7 +1208,8 @@ static void show_special(struct audit_context *context, int *call_panic) *call_panic = 1; } else { audit_log_format(ab, " obj=%s", ctx); - security_release_secctx(ctx, len); + lsmcontext_init(&lsmcxt, ctx, len, 0); + security_release_secctx(&lsmcxt); } } if (context->ipc.has_perm) { @@ -1352,6 +1356,7 @@ static void audit_log_name(struct audit_context *context, struct audit_names *n, char *ctx = NULL; u32 len; struct lsmblob blob; + struct lsmcontext lsmcxt; lsmblob_init(&blob, n->osid); if (security_secid_to_secctx(&blob, &ctx, &len)) { @@ -1360,7 +1365,8 @@ static void audit_log_name(struct audit_context *context, struct audit_names *n, *call_panic = 2; } else { audit_log_format(ab, " obj=%s", ctx); - security_release_secctx(ctx, len); + lsmcontext_init(&lsmcxt, ctx, len, 0); /* scaffolding */ + security_release_secctx(&lsmcxt); } } diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c index e05f4ef68bd8..7834c357b60b 100644 --- a/net/ipv4/ip_sockglue.c +++ b/net/ipv4/ip_sockglue.c @@ -130,6 +130,7 @@ static void ip_cmsg_recv_checksum(struct msghdr *msg, struct sk_buff *skb, static void ip_cmsg_recv_security(struct msghdr *msg, struct sk_buff *skb) { + struct lsmcontext context; struct lsmblob lb; char *secdata; u32 seclen; @@ -144,7 +145,8 @@ static void ip_cmsg_recv_security(struct msghdr *msg, struct sk_buff *skb) return; put_cmsg(msg, SOL_IP, SCM_SECURITY, seclen, secdata); - security_release_secctx(secdata, seclen); + lsmcontext_init(&context, secdata, seclen, 0); /* scaffolding */ + security_release_secctx(&context); } static void ip_cmsg_recv_dstaddr(struct msghdr *msg, struct sk_buff *skb) diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index ca0968f13240..6954e6600583 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -331,6 +331,7 @@ static int ctnetlink_dump_secctx(struct sk_buff *skb, const struct nf_conn *ct) int len, ret; char *secctx; struct lsmblob blob; + struct lsmcontext context; lsmblob_init(&blob, ct->secmark); ret = security_secid_to_secctx(&blob, &secctx, &len); @@ -348,7 +349,8 @@ static int ctnetlink_dump_secctx(struct sk_buff *skb, const struct nf_conn *ct) ret = 0; nla_put_failure: - security_release_secctx(secctx, len); + lsmcontext_init(&context, secctx, len, 0); /* scaffolding */ + security_release_secctx(&context); return ret; } #else diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c index c793103f3cd7..79158ad0486e 100644 --- a/net/netfilter/nf_conntrack_standalone.c +++ b/net/netfilter/nf_conntrack_standalone.c @@ -176,6 +176,7 @@ static void ct_show_secctx(struct seq_file *s, const struct nf_conn *ct) u32 len; char *secctx; struct lsmblob blob; + struct lsmcontext context; lsmblob_init(&blob, ct->secmark); ret = security_secid_to_secctx(&blob, &secctx, &len); @@ -184,7 +185,8 @@ static void ct_show_secctx(struct seq_file *s, const struct nf_conn *ct) seq_printf(s, "secctx=%s ", secctx); - security_release_secctx(secctx, len); + lsmcontext_init(&context, secctx, len, 0); /* scaffolding */ + security_release_secctx(&context); } #else static inline void ct_show_secctx(struct seq_file *s, const struct nf_conn *ct) diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c index 59211bff90ab..fe8403ef4e89 100644 --- a/net/netfilter/nfnetlink_queue.c +++ b/net/netfilter/nfnetlink_queue.c @@ -399,6 +399,7 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue, enum ip_conntrack_info uninitialized_var(ctinfo); struct nfnl_ct_hook *nfnl_ct; bool csum_verify; + struct lsmcontext scaff; /* scaffolding */ char *secdata = NULL; u32 seclen = 0; @@ -629,8 +630,10 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue, } nlh->nlmsg_len = skb->len; - if (seclen) - security_release_secctx(secdata, seclen); + if (seclen) { + lsmcontext_init(&scaff, secdata, seclen, 0); + security_release_secctx(&scaff); + } return skb; nla_put_failure: @@ -638,8 +641,10 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue, kfree_skb(skb); net_err_ratelimited("nf_queue: error creating packet message\n"); nlmsg_failure: - if (seclen) - security_release_secctx(secdata, seclen); + if (seclen) { + lsmcontext_init(&scaff, secdata, seclen, 0); + security_release_secctx(&scaff); + } return NULL; } diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c index 2294aa9471e6..15b1945853be 100644 --- a/net/netlabel/netlabel_unlabeled.c +++ b/net/netlabel/netlabel_unlabeled.c @@ -387,6 +387,7 @@ int netlbl_unlhsh_add(struct net *net, struct net_device *dev; struct netlbl_unlhsh_iface *iface; struct audit_buffer *audit_buf = NULL; + struct lsmcontext context; char *secctx = NULL; u32 secctx_len; struct lsmblob blob; @@ -457,7 +458,9 @@ int netlbl_unlhsh_add(struct net *net, &secctx, &secctx_len) == 0) { audit_log_format(audit_buf, " sec_obj=%s", secctx); - security_release_secctx(secctx, secctx_len); + /* scaffolding */ + lsmcontext_init(&context, secctx, secctx_len, 0); + security_release_secctx(&context); } audit_log_format(audit_buf, " res=%u", ret_val == 0 ? 1 : 0); audit_log_end(audit_buf); @@ -488,6 +491,7 @@ static int netlbl_unlhsh_remove_addr4(struct net *net, struct netlbl_unlhsh_addr4 *entry; struct audit_buffer *audit_buf; struct net_device *dev; + struct lsmcontext context; char *secctx; u32 secctx_len; struct lsmblob blob; @@ -516,7 +520,9 @@ static int netlbl_unlhsh_remove_addr4(struct net *net, security_secid_to_secctx(&blob, &secctx, &secctx_len) == 0) { audit_log_format(audit_buf, " sec_obj=%s", secctx); - security_release_secctx(secctx, secctx_len); + /* scaffolding */ + lsmcontext_init(&context, secctx, secctx_len, 0); + security_release_secctx(&context); } audit_log_format(audit_buf, " res=%u", entry != NULL ? 1 : 0); audit_log_end(audit_buf); @@ -553,6 +559,7 @@ static int netlbl_unlhsh_remove_addr6(struct net *net, struct netlbl_unlhsh_addr6 *entry; struct audit_buffer *audit_buf; struct net_device *dev; + struct lsmcontext context; char *secctx; u32 secctx_len; struct lsmblob blob; @@ -580,7 +587,8 @@ static int netlbl_unlhsh_remove_addr6(struct net *net, security_secid_to_secctx(&blob, &secctx, &secctx_len) == 0) { audit_log_format(audit_buf, " sec_obj=%s", secctx); - security_release_secctx(secctx, secctx_len); + lsmcontext_init(&context, secctx, secctx_len, 0); + security_release_secctx(&context); } audit_log_format(audit_buf, " res=%u", entry != NULL ? 1 : 0); audit_log_end(audit_buf); @@ -1094,6 +1102,7 @@ static int netlbl_unlabel_staticlist_gen(u32 cmd, int ret_val = -ENOMEM; struct netlbl_unlhsh_walk_arg *cb_arg = arg; struct net_device *dev; + struct lsmcontext context; void *data; u32 secid; char *secctx; @@ -1161,7 +1170,9 @@ static int netlbl_unlabel_staticlist_gen(u32 cmd, NLBL_UNLABEL_A_SECCTX, secctx_len, secctx); - security_release_secctx(secctx, secctx_len); + /* scaffolding */ + lsmcontext_init(&context, secctx, secctx_len, 0); + security_release_secctx(&context); if (ret_val != 0) goto list_cb_failure; diff --git a/net/netlabel/netlabel_user.c b/net/netlabel/netlabel_user.c index 2ccc6567e2a2..94aea4985b74 100644 --- a/net/netlabel/netlabel_user.c +++ b/net/netlabel/netlabel_user.c @@ -98,6 +98,7 @@ struct audit_buffer *netlbl_audit_start_common(int type, struct netlbl_audit *audit_info) { struct audit_buffer *audit_buf; + struct lsmcontext context; char *secctx; u32 secctx_len; struct lsmblob blob; @@ -117,7 +118,8 @@ struct audit_buffer *netlbl_audit_start_common(int type, if (audit_info->secid != 0 && security_secid_to_secctx(&blob, &secctx, &secctx_len) == 0) { audit_log_format(audit_buf, " subj=%s", secctx); - security_release_secctx(secctx, secctx_len); + lsmcontext_init(&context, secctx, secctx_len, 0);/*scaffolding*/ + security_release_secctx(&context); } return audit_buf; diff --git a/security/security.c b/security/security.c index c3c9bd88b7af..2b355c2a53f3 100644 --- a/security/security.c +++ b/security/security.c @@ -2135,17 +2135,23 @@ int security_secctx_to_secid(const char *secdata, u32 seclen, } EXPORT_SYMBOL(security_secctx_to_secid); -void security_release_secctx(char *secdata, u32 seclen) +void security_release_secctx(struct lsmcontext *cp) { struct security_hook_list *hp; - int *display = current->security; + bool found = false; hlist_for_each_entry(hp, &security_hook_heads.release_secctx, list) - if (display == NULL || *display == LSMBLOB_INVALID || - *display == hp->lsmid->slot) { - hp->hook.release_secctx(secdata, seclen); - return; + if (cp->slot == hp->lsmid->slot) { + hp->hook.release_secctx(cp->context, cp->len); + found = true; + break; } + + memset(cp, 0, sizeof(*cp)); + + if (!found) + pr_warn("%s context \"%s\" from slot %d not released\n", + __func__, cp->context, cp->slot); } EXPORT_SYMBOL(security_release_secctx); diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index 7a0ead4da479..472cb2097d36 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -4439,11 +4439,16 @@ static int smack_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid) return 0; } -/* - * There used to be a smack_release_secctx hook - * that did nothing back when hooks were in a vector. - * Now that there's a list such a hook adds cost. +/** + * smack_release_secctx - do everything necessary to free a context + * @secdata: Unused + * @seclen: Unused + * + * Do nothing but hold a slot in the hooks list. */ +static void smack_release_secctx(char *secdata, u32 seclen) +{ +} static int smack_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen) { @@ -4688,6 +4693,7 @@ static struct security_hook_list smack_hooks[] __lsm_ro_after_init = { LSM_HOOK_INIT(ismaclabel, smack_ismaclabel), LSM_HOOK_INIT(secid_to_secctx, smack_secid_to_secctx), LSM_HOOK_INIT(secctx_to_secid, smack_secctx_to_secid), + LSM_HOOK_INIT(release_secctx, smack_release_secctx), LSM_HOOK_INIT(inode_notifysecctx, smack_inode_notifysecctx), LSM_HOOK_INIT(inode_setsecctx, smack_inode_setsecctx), LSM_HOOK_INIT(inode_getsecctx, smack_inode_getsecctx), From patchwork Thu Aug 29 23:29:24 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 11122643 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 9AD8614DE for ; Thu, 29 Aug 2019 23:30:10 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 6531A2173E for ; Thu, 29 Aug 2019 23:30:10 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="n9OtQBci" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1725844AbfH2XaK (ORCPT ); Thu, 29 Aug 2019 19:30:10 -0400 Received: from sonic313-22.consmr.mail.bf2.yahoo.com ([74.6.133.196]:32989 "EHLO sonic313-22.consmr.mail.bf2.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728146AbfH2XaJ (ORCPT ); Thu, 29 Aug 2019 19:30:09 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1567121406; bh=hQ+s5PNyvomBRgAKxssT4xIDF7aQdUzpAGYOgkIB/B0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=n9OtQBciZpTaOKMP+kgWXtJKbEErjBnSfxpKPHkIHaUROCBcVUI3FN7Zs0KVcV7c5bdBIRbprlxtQkcKRUTT/3VF7Nq1gv00z1VRNxFF0M4GZ41hY1PA/g8+k1ooEGbquq0Vxbqv7thHvyVmbRk0FuYa/vQFsHRgHYnB7EMK7xmx7YmUv/N1b1os6cCWj94PzbiBONyyLW6CHyWJwyctG4Pi0PJg5c0Vnr0vtrXfr7rqv62ROhVzPUjUJEhsP/kRa/iHIzn8jCgMtD82yfLQh792sbc+wyI4aQ9dyMB6AczncU5eh2o1xETJNta2UfYiLSsm8xU9tyUtT6s86yIFAg== X-YMail-OSG: FvyjoAQVM1k_Db3qbI9i1HlYqze_2uvd5JL0b4yDZonpPwYhb0esalUeK0bMJ3G OLIZq3VAPaKNjj5T_D7LoOWk_9zM80gE1NaZOsIE1FusGY.q49F22zsyP2vHtYc2hN5hdMDtFqvI jPTkTrBt6lQQnA3SZMgdGhvoeAe8xmJEd80rbCg4U6vvnVnaAWSd2e9feGQx7B6bYyDtoXw5sp1n VwOREu76pfsD5GmC3jIewLOxxWCvueb.04v92yQMr5OSsN4Af_fpWJ0hGtoxg8yAyAV7eNwuAGiE rWt4fYwAVchhqXnt8ofpoGjPBthVAoqdsz7v5EMl1UWji7QCIuS_Va2t56pdUmZYmFsjYsnIF4eW IcVTjPZsvtOsPnzU8UPwP5lHvQmV.PDBfwtu61MbbjUyb7oKI3XxX3kTAEfrPTkbVR3ZUXRcRYpv cBGLX1hkOapvMR9F9sXNGtTMA1UmXpSiCs1rA0dQEKHfLUagRXB7ulj9p2uEpCQSludGS6EawcVn ggAvfgVqlEfm.gLY9gQfJqU801aK9uJzVBlimtVSFVrRllSmaUeSIjkaZjGXhzy3CqlehDeA.xlD IL1ljm7zrzRswpzAoKsW2wm0iIxSayc1E0G0eeS4rOn9zuYNUzgOFK1voC69QcOW3nVeCXO5j4B_ QlBSqbX5RtIAKGab58gYwiP3eBwhrRcjhc1n0qQkG5QxBTEnS2bMsDOvPWoQWBs7q5in4SB7k75j MLsDRtAxfOuj5Sdxq0pTXwum5EEaSGjPC3gCFEg8y0vGFYSo54YHTuj4IZV88sINE9VhvSuC.Cge .wAxn8WfNNCm7v3WfExtl0uUP2BAUVnAERkhkyao5DSgtRiMvnTXmWPrw4tulmQL9EPfNQlvJuNY TXs9rNIfvv8rC4A7BRzwYZhE1p_tG_IvQYfiSGnn5hyUEkIJXEhLrTuAFCsyXjQlmLdx.GLNtSb4 8Z8w7iPvqt9yUK9I1DZGrCVnMgQOkbEoXalez0JOjTwIf2qNOuNAPGGf9EsUJJjbphYH5zoksLjM 8GBNH.4JMRmnvu30GXQUmiRUN_wYOouna_e2sP5FR7usr24ZhzI6M9KQD.taq2tbmCbbvN92S8kL 7.k4xgEJKgklS0_1XMB8xx6Y.RcOfjlkiDwS_NfpCwicO.GdxonGWwrCfayJWGkhmBucLtjMNw6i iRQqfUUo2Y1NF7bzCuVNywnv2TW0NfPGawnlxnHYGISthZgcF2EzPGBfeleJDAzOuBWPgwqru7N6 9W98YATyBPIZgYWEQVVG288y1Z2nW9Q.mKUpdyldQxbppfiopCkSb7hmeMZY3kxIAVLsmoVXWy0O wFA-- Received: from sonic.gate.mail.ne1.yahoo.com by sonic313.consmr.mail.bf2.yahoo.com with HTTP; Thu, 29 Aug 2019 23:30:06 +0000 Received: by smtp408.mail.bf1.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID 2d799b9799b92d4529ae6bd2b9fbf9fb; Thu, 29 Aug 2019 23:30:05 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, jmorris@namei.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org Cc: casey@schaufler-ca.com, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, paul@paul-moore.com, sds@tycho.nsa.gov Subject: [PATCH v8 17/28] LSM: Use lsmcontext in security_secid_to_secctx Date: Thu, 29 Aug 2019 16:29:24 -0700 Message-Id: <20190829232935.7099-18-casey@schaufler-ca.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190829232935.7099-1-casey@schaufler-ca.com> References: <20190829232935.7099-1-casey@schaufler-ca.com> MIME-Version: 1.0 Sender: selinux-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: selinux@vger.kernel.org Replace the (secctx,seclen) pointer pair with a single lsmcontext pointer to allow return of the LSM identifier along with the context and context length. This allows security_release_secctx() to know how to release the context. Callers have been modified to use or save the returned data from the new structure. Signed-off-by: Casey Schaufler --- drivers/android/binder.c | 24 ++++++--------- include/linux/security.h | 4 +-- include/net/scm.h | 10 ++----- kernel/audit.c | 29 +++++++----------- kernel/auditsc.c | 31 +++++++------------ net/ipv4/ip_sockglue.c | 7 ++--- net/netfilter/nf_conntrack_netlink.c | 14 +++++---- net/netfilter/nf_conntrack_standalone.c | 7 ++--- net/netfilter/nfnetlink_queue.c | 5 +++- net/netlabel/netlabel_unlabeled.c | 40 ++++++++----------------- net/netlabel/netlabel_user.c | 7 ++--- security/security.c | 10 +++++-- 12 files changed, 73 insertions(+), 115 deletions(-) diff --git a/drivers/android/binder.c b/drivers/android/binder.c index 89e574be34cc..90bc4ce07cd2 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -2874,9 +2874,7 @@ static void binder_transaction(struct binder_proc *proc, binder_size_t last_fixup_min_off = 0; struct binder_context *context = proc->context; int t_debug_id = atomic_inc_return(&binder_last_id); - char *secctx = NULL; - u32 secctx_sz = 0; - struct lsmcontext scaff; /* scaffolding */ + struct lsmcontext lsmctx = { }; e = binder_transaction_log_add(&binder_transaction_log); e->debug_id = t_debug_id; @@ -3123,14 +3121,14 @@ static void binder_transaction(struct binder_proc *proc, struct lsmblob blob; security_task_getsecid(proc->tsk, &blob); - ret = security_secid_to_secctx(&blob, &secctx, &secctx_sz); + ret = security_secid_to_secctx(&blob, &lsmctx); if (ret) { return_error = BR_FAILED_REPLY; return_error_param = ret; return_error_line = __LINE__; goto err_get_secctx_failed; } - extra_buffers_size += ALIGN(secctx_sz, sizeof(u64)); + extra_buffers_size += ALIGN(lsmctx.len, sizeof(u64)); } trace_binder_transaction(reply, t, target_node); @@ -3149,19 +3147,17 @@ static void binder_transaction(struct binder_proc *proc, t->buffer = NULL; goto err_binder_alloc_buf_failed; } - if (secctx) { + if (lsmctx.context) { size_t buf_offset = ALIGN(tr->data_size, sizeof(void *)) + ALIGN(tr->offsets_size, sizeof(void *)) + ALIGN(extra_buffers_size, sizeof(void *)) - - ALIGN(secctx_sz, sizeof(u64)); + ALIGN(lsmctx.len, sizeof(u64)); t->security_ctx = (uintptr_t)t->buffer->user_data + buf_offset; binder_alloc_copy_to_buffer(&target_proc->alloc, t->buffer, buf_offset, - secctx, secctx_sz); - lsmcontext_init(&scaff, secctx, secctx_sz, 0); - security_release_secctx(&scaff); - secctx = NULL; + lsmctx.context, lsmctx.len); + security_release_secctx(&lsmctx); } t->buffer->debug_id = t->debug_id; t->buffer->transaction = t; @@ -3481,10 +3477,8 @@ static void binder_transaction(struct binder_proc *proc, t->buffer->transaction = NULL; binder_alloc_free_buf(&target_proc->alloc, t->buffer); err_binder_alloc_buf_failed: - if (secctx) { - lsmcontext_init(&scaff, secctx, secctx_sz, 0); - security_release_secctx(&scaff); - } + if (lsmctx.context) + security_release_secctx(&lsmctx); err_get_secctx_failed: kfree(tcomplete); binder_stats_deleted(BINDER_STAT_TRANSACTION_COMPLETE); diff --git a/include/linux/security.h b/include/linux/security.h index 046012a7255f..7255825aa697 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -481,7 +481,7 @@ int security_setprocattr(const char *lsm, const char *name, void *value, size_t size); int security_netlink_send(struct sock *sk, struct sk_buff *skb); int security_ismaclabel(const char *name); -int security_secid_to_secctx(struct lsmblob *blob, char **secdata, u32 *seclen); +int security_secid_to_secctx(struct lsmblob *blob, struct lsmcontext *cp); int security_secctx_to_secid(const char *secdata, u32 seclen, struct lsmblob *blob); void security_release_secctx(struct lsmcontext *cp); @@ -1263,7 +1263,7 @@ static inline int security_ismaclabel(const char *name) } static inline int security_secid_to_secctx(struct lsmblob *blob, - char **secdata, u32 *seclen) + struct lsmcontext *cp) { return -EOPNOTSUPP; } diff --git a/include/net/scm.h b/include/net/scm.h index 30ba801c91bd..4a6ad8caf423 100644 --- a/include/net/scm.h +++ b/include/net/scm.h @@ -93,18 +93,14 @@ static __inline__ int scm_send(struct socket *sock, struct msghdr *msg, static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm) { struct lsmcontext context; - char *secdata; - u32 seclen; int err; if (test_bit(SOCK_PASSSEC, &sock->flags)) { - err = security_secid_to_secctx(&scm->lsmblob, &secdata, - &seclen); + err = security_secid_to_secctx(&scm->lsmblob, &context); if (!err) { - put_cmsg(msg, SOL_SOCKET, SCM_SECURITY, seclen, secdata); - /*scaffolding*/ - lsmcontext_init(&context, secdata, seclen, 0); + put_cmsg(msg, SOL_SOCKET, SCM_SECURITY, + context.len, context.context); security_release_secctx(&context); } } diff --git a/kernel/audit.c b/kernel/audit.c index f844a2a642e6..e1dfd9c6df36 100644 --- a/kernel/audit.c +++ b/kernel/audit.c @@ -1191,9 +1191,8 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) struct audit_buffer *ab; u16 msg_type = nlh->nlmsg_type; struct audit_sig_info *sig_data; - char *ctx = NULL; u32 len; - struct lsmcontext scaff; /* scaffolding */ + struct lsmcontext context = { }; err = audit_netlink_ok(skb, msg_type); if (err) @@ -1431,25 +1430,22 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) case AUDIT_SIGNAL_INFO: len = 0; if (lsmblob_is_set(&audit_sig_lsm)) { - err = security_secid_to_secctx(&audit_sig_lsm, &ctx, - &len); + err = security_secid_to_secctx(&audit_sig_lsm, + &context); if (err) return err; } sig_data = kmalloc(sizeof(*sig_data) + len, GFP_KERNEL); if (!sig_data) { - if (lsmblob_is_set(&audit_sig_lsm)) { - lsmcontext_init(&scaff, ctx, len, 0); - security_release_secctx(&scaff); - } + if (lsmblob_is_set(&audit_sig_lsm)) + security_release_secctx(&context); return -ENOMEM; } sig_data->uid = from_kuid(&init_user_ns, audit_sig_uid); sig_data->pid = audit_sig_pid; if (lsmblob_is_set(&audit_sig_lsm)) { - memcpy(sig_data->ctx, ctx, len); - lsmcontext_init(&scaff, ctx, len, 0); - security_release_secctx(&scaff); + memcpy(sig_data->ctx, context.context, context.len); + security_release_secctx(&context); } audit_send_reply(skb, seq, AUDIT_SIGNAL_INFO, 0, 0, sig_data, sizeof(*sig_data) + len); @@ -2074,26 +2070,23 @@ void audit_log_key(struct audit_buffer *ab, char *key) int audit_log_task_context(struct audit_buffer *ab) { - char *ctx = NULL; - unsigned len; int error; struct lsmblob blob; - struct lsmcontext scaff; /* scaffolding */ + struct lsmcontext context; security_task_getsecid(current, &blob); if (!lsmblob_is_set(&blob)) return 0; - error = security_secid_to_secctx(&blob, &ctx, &len); + error = security_secid_to_secctx(&blob, &context); if (error) { if (error != -EINVAL) goto error_path; return 0; } - audit_log_format(ab, " subj=%s", ctx); - lsmcontext_init(&scaff, ctx, len, 0); - security_release_secctx(&scaff); + audit_log_format(ab, " subj=%s", context.context); + security_release_secctx(&context); return 0; error_path: diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 9fab0e7d90c3..0478680cd0a8 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -943,9 +943,7 @@ static int audit_log_pid_context(struct audit_context *context, pid_t pid, struct lsmblob *blob, char *comm) { struct audit_buffer *ab; - struct lsmcontext lsmcxt; - char *ctx = NULL; - u32 len; + struct lsmcontext lsmctx; int rc = 0; ab = audit_log_start(context, GFP_KERNEL, AUDIT_OBJ_PID); @@ -956,13 +954,12 @@ static int audit_log_pid_context(struct audit_context *context, pid_t pid, from_kuid(&init_user_ns, auid), from_kuid(&init_user_ns, uid), sessionid); if (lsmblob_is_set(blob)) { - if (security_secid_to_secctx(blob, &ctx, &len)) { + if (security_secid_to_secctx(blob, &lsmctx)) { audit_log_format(ab, " obj=(none)"); rc = 1; } else { - audit_log_format(ab, " obj=%s", ctx); - lsmcontext_init(&lsmcxt, ctx, len, 0); /*scaffolding*/ - security_release_secctx(&lsmcxt); + audit_log_format(ab, " obj=%s", lsmctx.context); + security_release_secctx(&lsmctx); } } audit_log_format(ab, " ocomm="); @@ -1174,7 +1171,6 @@ static void audit_log_fcaps(struct audit_buffer *ab, struct audit_names *name) static void show_special(struct audit_context *context, int *call_panic) { - struct lsmcontext lsmcxt; struct audit_buffer *ab; int i; @@ -1198,17 +1194,15 @@ static void show_special(struct audit_context *context, int *call_panic) from_kgid(&init_user_ns, context->ipc.gid), context->ipc.mode); if (osid) { - char *ctx = NULL; - u32 len; + struct lsmcontext lsmcxt; struct lsmblob blob; lsmblob_init(&blob, osid); - if (security_secid_to_secctx(&blob, &ctx, &len)) { + if (security_secid_to_secctx(&blob, &lsmcxt)) { audit_log_format(ab, " osid=%u", osid); *call_panic = 1; } else { - audit_log_format(ab, " obj=%s", ctx); - lsmcontext_init(&lsmcxt, ctx, len, 0); + audit_log_format(ab, " obj=%s", lsmcxt.context); security_release_secctx(&lsmcxt); } } @@ -1353,20 +1347,17 @@ static void audit_log_name(struct audit_context *context, struct audit_names *n, MAJOR(n->rdev), MINOR(n->rdev)); if (n->osid != 0) { - char *ctx = NULL; - u32 len; struct lsmblob blob; - struct lsmcontext lsmcxt; + struct lsmcontext lsmctx; lsmblob_init(&blob, n->osid); - if (security_secid_to_secctx(&blob, &ctx, &len)) { + if (security_secid_to_secctx(&blob, &lsmctx)) { audit_log_format(ab, " osid=%u", n->osid); if (call_panic) *call_panic = 2; } else { - audit_log_format(ab, " obj=%s", ctx); - lsmcontext_init(&lsmcxt, ctx, len, 0); /* scaffolding */ - security_release_secctx(&lsmcxt); + audit_log_format(ab, " obj=%s", lsmctx.context); + security_release_secctx(&lsmctx); } } diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c index 7834c357b60b..80ae0c5a1301 100644 --- a/net/ipv4/ip_sockglue.c +++ b/net/ipv4/ip_sockglue.c @@ -132,20 +132,17 @@ static void ip_cmsg_recv_security(struct msghdr *msg, struct sk_buff *skb) { struct lsmcontext context; struct lsmblob lb; - char *secdata; - u32 seclen; int err; err = security_socket_getpeersec_dgram(NULL, skb, &lb); if (err) return; - err = security_secid_to_secctx(&lb, &secdata, &seclen); + err = security_secid_to_secctx(&lb, &context); if (err) return; - put_cmsg(msg, SOL_IP, SCM_SECURITY, seclen, secdata); - lsmcontext_init(&context, secdata, seclen, 0); /* scaffolding */ + put_cmsg(msg, SOL_IP, SCM_SECURITY, context.len, context.context); security_release_secctx(&context); } diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index 6954e6600583..403307ff0fff 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -328,13 +328,12 @@ static int ctnetlink_dump_mark(struct sk_buff *skb, const struct nf_conn *ct) static int ctnetlink_dump_secctx(struct sk_buff *skb, const struct nf_conn *ct) { struct nlattr *nest_secctx; - int len, ret; - char *secctx; + int ret; struct lsmblob blob; struct lsmcontext context; lsmblob_init(&blob, ct->secmark); - ret = security_secid_to_secctx(&blob, &secctx, &len); + ret = security_secid_to_secctx(&blob, &context); if (ret) return 0; @@ -343,13 +342,12 @@ static int ctnetlink_dump_secctx(struct sk_buff *skb, const struct nf_conn *ct) if (!nest_secctx) goto nla_put_failure; - if (nla_put_string(skb, CTA_SECCTX_NAME, secctx)) + if (nla_put_string(skb, CTA_SECCTX_NAME, context.context)) goto nla_put_failure; nla_nest_end(skb, nest_secctx); ret = 0; nla_put_failure: - lsmcontext_init(&context, secctx, len, 0); /* scaffolding */ security_release_secctx(&context); return ret; } @@ -620,12 +618,16 @@ static inline int ctnetlink_secctx_size(const struct nf_conn *ct) #ifdef CONFIG_NF_CONNTRACK_SECMARK int len, ret; struct lsmblob blob; + struct lsmcontext context; lsmblob_init(&blob, ct->secmark); - ret = security_secid_to_secctx(&blob, NULL, &len); + ret = security_secid_to_secctx(&blob, &context); if (ret) return 0; + len = context.len; + security_release_secctx(&context); + return nla_total_size(0) /* CTA_SECCTX */ + nla_total_size(sizeof(char) * len); /* CTA_SECCTX_NAME */ #else diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c index 79158ad0486e..fcb51ab2bb8b 100644 --- a/net/netfilter/nf_conntrack_standalone.c +++ b/net/netfilter/nf_conntrack_standalone.c @@ -173,19 +173,16 @@ static void ct_seq_stop(struct seq_file *s, void *v) static void ct_show_secctx(struct seq_file *s, const struct nf_conn *ct) { int ret; - u32 len; - char *secctx; struct lsmblob blob; struct lsmcontext context; lsmblob_init(&blob, ct->secmark); - ret = security_secid_to_secctx(&blob, &secctx, &len); + ret = security_secid_to_secctx(&blob, &context); if (ret) return; - seq_printf(s, "secctx=%s ", secctx); + seq_printf(s, "secctx=%s ", context.context); - lsmcontext_init(&context, secctx, len, 0); /* scaffolding */ security_release_secctx(&context); } #else diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c index fe8403ef4e89..5593ee05d106 100644 --- a/net/netfilter/nfnetlink_queue.c +++ b/net/netfilter/nfnetlink_queue.c @@ -310,6 +310,7 @@ static u32 nfqnl_get_sk_secctx(struct sk_buff *skb, char **secdata) u32 seclen = 0; #if IS_ENABLED(CONFIG_NETWORK_SECMARK) struct lsmblob blob; + struct lsmcontext context = { }; if (!skb || !sk_fullsock(skb->sk)) return 0; @@ -318,10 +319,12 @@ static u32 nfqnl_get_sk_secctx(struct sk_buff *skb, char **secdata) if (skb->secmark) { lsmblob_init(&blob, skb->secmark); - security_secid_to_secctx(&blob, secdata, &seclen); + security_secid_to_secctx(&blob, &context); + *secdata = context.context; } read_unlock_bh(&skb->sk->sk_callback_lock); + seclen = context.len; #endif return seclen; } diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c index 15b1945853be..4716e0011ba5 100644 --- a/net/netlabel/netlabel_unlabeled.c +++ b/net/netlabel/netlabel_unlabeled.c @@ -388,8 +388,6 @@ int netlbl_unlhsh_add(struct net *net, struct netlbl_unlhsh_iface *iface; struct audit_buffer *audit_buf = NULL; struct lsmcontext context; - char *secctx = NULL; - u32 secctx_len; struct lsmblob blob; if (addr_len != sizeof(struct in_addr) && @@ -454,12 +452,9 @@ int netlbl_unlhsh_add(struct net *net, rcu_read_unlock(); if (audit_buf != NULL) { lsmblob_init(&blob, secid); - if (security_secid_to_secctx(&blob, - &secctx, - &secctx_len) == 0) { - audit_log_format(audit_buf, " sec_obj=%s", secctx); - /* scaffolding */ - lsmcontext_init(&context, secctx, secctx_len, 0); + if (security_secid_to_secctx(&blob, &context) == 0) { + audit_log_format(audit_buf, " sec_obj=%s", + context.context); security_release_secctx(&context); } audit_log_format(audit_buf, " res=%u", ret_val == 0 ? 1 : 0); @@ -492,8 +487,6 @@ static int netlbl_unlhsh_remove_addr4(struct net *net, struct audit_buffer *audit_buf; struct net_device *dev; struct lsmcontext context; - char *secctx; - u32 secctx_len; struct lsmblob blob; spin_lock(&netlbl_unlhsh_lock); @@ -517,11 +510,9 @@ static int netlbl_unlhsh_remove_addr4(struct net *net, if (entry != NULL) lsmblob_init(&blob, entry->secid); if (entry != NULL && - security_secid_to_secctx(&blob, - &secctx, &secctx_len) == 0) { - audit_log_format(audit_buf, " sec_obj=%s", secctx); - /* scaffolding */ - lsmcontext_init(&context, secctx, secctx_len, 0); + security_secid_to_secctx(&blob, &context) == 0) { + audit_log_format(audit_buf, " sec_obj=%s", + context.context); security_release_secctx(&context); } audit_log_format(audit_buf, " res=%u", entry != NULL ? 1 : 0); @@ -560,8 +551,6 @@ static int netlbl_unlhsh_remove_addr6(struct net *net, struct audit_buffer *audit_buf; struct net_device *dev; struct lsmcontext context; - char *secctx; - u32 secctx_len; struct lsmblob blob; spin_lock(&netlbl_unlhsh_lock); @@ -584,10 +573,9 @@ static int netlbl_unlhsh_remove_addr6(struct net *net, if (entry != NULL) lsmblob_init(&blob, entry->secid); if (entry != NULL && - security_secid_to_secctx(&blob, - &secctx, &secctx_len) == 0) { - audit_log_format(audit_buf, " sec_obj=%s", secctx); - lsmcontext_init(&context, secctx, secctx_len, 0); + security_secid_to_secctx(&blob, &context) == 0) { + audit_log_format(audit_buf, " sec_obj=%s", + context.context); security_release_secctx(&context); } audit_log_format(audit_buf, " res=%u", entry != NULL ? 1 : 0); @@ -1105,8 +1093,6 @@ static int netlbl_unlabel_staticlist_gen(u32 cmd, struct lsmcontext context; void *data; u32 secid; - char *secctx; - u32 secctx_len; struct lsmblob blob; data = genlmsg_put(cb_arg->skb, NETLINK_CB(cb_arg->nl_cb->skb).portid, @@ -1163,15 +1149,13 @@ static int netlbl_unlabel_staticlist_gen(u32 cmd, } lsmblob_init(&blob, secid); - ret_val = security_secid_to_secctx(&blob, &secctx, &secctx_len); + ret_val = security_secid_to_secctx(&blob, &context); if (ret_val != 0) goto list_cb_failure; ret_val = nla_put(cb_arg->skb, NLBL_UNLABEL_A_SECCTX, - secctx_len, - secctx); - /* scaffolding */ - lsmcontext_init(&context, secctx, secctx_len, 0); + context.len, + context.context); security_release_secctx(&context); if (ret_val != 0) goto list_cb_failure; diff --git a/net/netlabel/netlabel_user.c b/net/netlabel/netlabel_user.c index 94aea4985b74..2d1307f65250 100644 --- a/net/netlabel/netlabel_user.c +++ b/net/netlabel/netlabel_user.c @@ -99,8 +99,6 @@ struct audit_buffer *netlbl_audit_start_common(int type, { struct audit_buffer *audit_buf; struct lsmcontext context; - char *secctx; - u32 secctx_len; struct lsmblob blob; if (audit_enabled == AUDIT_OFF) @@ -116,9 +114,8 @@ struct audit_buffer *netlbl_audit_start_common(int type, lsmblob_init(&blob, audit_info->secid); if (audit_info->secid != 0 && - security_secid_to_secctx(&blob, &secctx, &secctx_len) == 0) { - audit_log_format(audit_buf, " subj=%s", secctx); - lsmcontext_init(&context, secctx, secctx_len, 0);/*scaffolding*/ + security_secid_to_secctx(&blob, &context) == 0) { + audit_log_format(audit_buf, " subj=%s", context.context); security_release_secctx(&context); } diff --git a/security/security.c b/security/security.c index 2b355c2a53f3..38e10f92dae3 100644 --- a/security/security.c +++ b/security/security.c @@ -2100,18 +2100,22 @@ int security_ismaclabel(const char *name) } EXPORT_SYMBOL(security_ismaclabel); -int security_secid_to_secctx(struct lsmblob *blob, char **secdata, u32 *seclen) +int security_secid_to_secctx(struct lsmblob *blob, struct lsmcontext *cp) { struct security_hook_list *hp; int display = lsm_task_display(current); + memset(cp, 0, sizeof(*cp)); + hlist_for_each_entry(hp, &security_hook_heads.secid_to_secctx, list) { if (WARN_ON(hp->lsmid->slot < 0 || hp->lsmid->slot >= lsm_slot)) continue; - if (display == LSMBLOB_INVALID || display == hp->lsmid->slot) + if (display == LSMBLOB_INVALID || display == hp->lsmid->slot) { + cp->slot = hp->lsmid->slot; return hp->hook.secid_to_secctx( blob->secid[hp->lsmid->slot], - secdata, seclen); + &cp->context, &cp->len); + } } return 0; } From patchwork Thu Aug 29 23:29:25 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 11122649 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 3262814E5 for ; Thu, 29 Aug 2019 23:30:14 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 127F821874 for ; Thu, 29 Aug 2019 23:30:14 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="at4dMtko" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727783AbfH2XaN (ORCPT ); Thu, 29 Aug 2019 19:30:13 -0400 Received: from sonic311-23.consmr.mail.bf2.yahoo.com ([74.6.131.197]:45538 "EHLO sonic311-23.consmr.mail.bf2.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728192AbfH2XaN (ORCPT ); Thu, 29 Aug 2019 19:30:13 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1567121412; bh=IutdtSBU3rdIdoae04O6ta5dHJ02n75/QIG5JBsSLr8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=at4dMtkoJgd9zhzjX+MLaOnHK2kDz9k9YI11w7bpH3SLxbdsFFe9UoTFA2qb6U7rYW4KaEwGXEcIAYpk9a6zt9VWwQhEaWxBysbfajScnUEQmWdA/4BsQHIMpU4855/Kg7cTRJjEoGjUkonKHEb5mudrVl5WTLVvi2U919PEwOKiPXYJEAbNEGr/uGhcCz/q5sNd7n+TR113K/ypsOUyPeUvR2T9RCoF6lxIOog16gaXsY7lZcjQZSxcRH0i9H2kUghyVQWUFPbeJppy6gYqS1VMgajOsaAdlnZacK+7feDsoGDl138ZDsvHmcZIl9Ei+JzXFVapVawl+lW5S6j1UQ== X-YMail-OSG: CUM9YQwVM1mcge08sBoMkMD8WUDmUFxHdA1X5RCjPfBAuimuVT0EQ.GbOqjraD5 .NGl_UjoQmup187PC5IDleO_1H0Rzd2JqD0TPP.DPw27vi1SmoSzU7WmKjW6loK9KR_KcNeJFOou EWaJIV98bbEAyxArXRPKdpArc3Ah_8X79VJNjm5Z8C2O3Gpw19d83dgSDoCRYZ0ctYtfhk3OiH5h 9rD99LsioCR3nS_B1x4y3QgK8I44g2XMpDIPohqECQcPG7DV.w.Gdxo4zQFYZVYMQ.ODU2OroBrE KwTUFKgBf71qflLYWyWgD4BNDpJyMu.1hHgc9WQcoLg7VQXnvP2EIgpdrxfnoqpOdF4tJSM0XWsn tQ9h9zXi3FS5YfwDlsg4YSoNjKoUzK0d8VJ4Ja.z_qj8bDCnWvnwhO3WVZ.HEpNy.jPyksWCui6a wlrT.M_UCu9UNMTtoS07WbO42TMB2FVIVBcB00xHIGxZpYs4tJD6hucAeVawYwJ4efVi2u7sWxhP fihLna6pLTMo3WhdgippdLB69qB_VU2fc_VAklQAZSeAEKlwNAaEus0zFqp6ug9E.sWPW8LeG5aV RMepnNxslszowOU1UaTGOvXqINiE7yNy7GIkBXgZ1L1wZA3nnmJUnm3e4uaQwBeg27i5sJ3LtFqP OG2sVRT3KpvvXHgLrlNKN6OA_O0efkS7MQ0lLt72G_b4bfrqqQjeEr4L3ckq3UsC8gjj0tmX84ff PR2rexOh2aL8S0kzgkNgiwEi.Mk8QsF0pC09ukXpGJHY4ubdqv7xjGHvv2g0NFhvS2ZhME98WeVo d6F74pOO5a1pPhHOaWluwmRhKt.MkWNH3ipoyCghdv7d41wczEbFjpxiEkmqgOoRDe8WTebu3WSF uqh4u0bjdbfrqPgBhiLlPteqmKLPxFTcB50YiFwY.1.t7DoiLDtUaeG1PThH_mxYMeedbH8xSTHT EQVtj8TLM9H3j5mI_enuURXcjYAwFC4NkIGRjrATp.fdiYoTHu_YFhYnKnciupvj9Hv0oSPM76EQ YECRZQcwtGae1iSDsdmODKUrKB8Vz1uQ1S6rzIC63vyXf4mFrO4g7XXpjvhTE6DFjSExAYfgqhxn dPIbmCl.z8bsihtuoklwICOfWeog.O1C4wWReJbGPKonNlm0i8PmU5L14zMsO8CZBPw.pyliZhvG v.rkmp4Pjuk07ryYNqvUNU1LPzbqQptU9oNSKM9LT8J7Ov1IDmR36Byyho3MUYLcSZp9tW3i39Vd P7UVfZVa70SIfukBgatjLY96I.T_puvfs0HWDqLYampzj6.eA9OnTStnRTsOBkYePSeLBMTxazTe K6U4jMTgbdQ-- Received: from sonic.gate.mail.ne1.yahoo.com by sonic311.consmr.mail.bf2.yahoo.com with HTTP; Thu, 29 Aug 2019 23:30:12 +0000 Received: by smtp408.mail.bf1.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID 2d799b9799b92d4529ae6bd2b9fbf9fb; Thu, 29 Aug 2019 23:30:08 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, jmorris@namei.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org Cc: casey@schaufler-ca.com, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, paul@paul-moore.com, sds@tycho.nsa.gov Subject: [PATCH v8 18/28] LSM: Use lsmcontext in security_dentry_init_security Date: Thu, 29 Aug 2019 16:29:25 -0700 Message-Id: <20190829232935.7099-19-casey@schaufler-ca.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190829232935.7099-1-casey@schaufler-ca.com> References: <20190829232935.7099-1-casey@schaufler-ca.com> MIME-Version: 1.0 Sender: selinux-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: selinux@vger.kernel.org Change the security_dentry_init_security() interface to fill an lsmcontext structure instead of a void * data area and a length. The lone caller of this interface is NFS4, which may make copies of the data using its own mechanisms. A rework of the nfs4 code to use the lsmcontext properly is a significant project, so the coward's way out is taken, and the lsmcontext data from security_dentry_init_security() is copied, then released directly. This interface does not use the "display". There is currently not case where that is useful or reasonable. Reviewed-by: Kees Cook Reviewed-by: John Johansen Signed-off-by: Casey Schaufler --- fs/nfs/nfs4proc.c | 26 ++++++++++++++++---------- include/linux/security.h | 7 +++---- security/security.c | 29 +++++++++++++++++++++++++---- 3 files changed, 44 insertions(+), 18 deletions(-) diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index af1c0db29c39..952f805965bb 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -113,6 +113,7 @@ static inline struct nfs4_label * nfs4_label_init_security(struct inode *dir, struct dentry *dentry, struct iattr *sattr, struct nfs4_label *label) { + struct lsmcontext context; int err; if (label == NULL) @@ -122,21 +123,26 @@ nfs4_label_init_security(struct inode *dir, struct dentry *dentry, return NULL; err = security_dentry_init_security(dentry, sattr->ia_mode, - &dentry->d_name, (void **)&label->label, &label->len); - if (err == 0) - return label; + &dentry->d_name, &context); + + if (err) + return NULL; + + label->label = kmemdup(context.context, context.len, GFP_KERNEL); + if (label->label == NULL) + label = NULL; + else + label->len = context.len; + + security_release_secctx(&context); + + return label; - return NULL; } static inline void nfs4_label_release_security(struct nfs4_label *label) { - struct lsmcontext scaff; /* scaffolding */ - - if (label) { - lsmcontext_init(&scaff, label->label, label->len, 0); - security_release_secctx(&scaff); - } + kfree(label->label); } static inline u32 *nfs4_bitmask(struct nfs_server *server, struct nfs4_label *label) { diff --git a/include/linux/security.h b/include/linux/security.h index 7255825aa697..2674eb70c2d7 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -352,8 +352,8 @@ int security_sb_clone_mnt_opts(const struct super_block *oldsb, int security_add_mnt_opt(const char *option, const char *val, int len, void **mnt_opts); int security_dentry_init_security(struct dentry *dentry, int mode, - const struct qstr *name, void **ctx, - u32 *ctxlen); + const struct qstr *name, + struct lsmcontext *ctx); int security_dentry_create_files_as(struct dentry *dentry, int mode, struct qstr *name, const struct cred *old, @@ -724,8 +724,7 @@ static inline void security_inode_free(struct inode *inode) static inline int security_dentry_init_security(struct dentry *dentry, int mode, const struct qstr *name, - void **ctx, - u32 *ctxlen) + struct lsmcontext *ctx) { return -EOPNOTSUPP; } diff --git a/security/security.c b/security/security.c index 38e10f92dae3..7bbc17cc212d 100644 --- a/security/security.c +++ b/security/security.c @@ -1029,12 +1029,33 @@ void security_inode_free(struct inode *inode) inode_free_by_rcu); } +/* + * security_dentry_init_security - initial context for a dentry + * @dentry: directory entry + * @mode: access mode + * @name: path name + * @context: resulting security context + * + * Use at most one security module to get the initial + * security context. Do not use the "display". + * + * Returns -EOPNOTSUPP if not supplied by any module or the module result. + */ int security_dentry_init_security(struct dentry *dentry, int mode, - const struct qstr *name, void **ctx, - u32 *ctxlen) + const struct qstr *name, + struct lsmcontext *cp) { - return call_int_hook(dentry_init_security, -EOPNOTSUPP, dentry, mode, - name, ctx, ctxlen); + struct security_hook_list *hp; + + hlist_for_each_entry(hp, &security_hook_heads.dentry_init_security, + list) { + cp->slot = hp->lsmid->slot; + return hp->hook.dentry_init_security(dentry, mode, name, + (void **)&cp->context, + &cp->len); + } + + return -EOPNOTSUPP; } EXPORT_SYMBOL(security_dentry_init_security); From patchwork Thu Aug 29 23:29:26 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 11122653 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 92AF9112C for ; Thu, 29 Aug 2019 23:30:16 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 64C7E21874 for ; Thu, 29 Aug 2019 23:30:16 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="m3/56eW/" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728282AbfH2XaQ (ORCPT ); Thu, 29 Aug 2019 19:30:16 -0400 Received: from sonic316-20.consmr.mail.bf2.yahoo.com ([74.6.130.194]:41835 "EHLO sonic316-20.consmr.mail.bf2.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728192AbfH2XaP (ORCPT ); Thu, 29 Aug 2019 19:30:15 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1567121413; bh=wO8BecnQoqaHN1sZDLFG42uMEVV7cUUKef4nGhQwWSo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=m3/56eW/r/RGupTNN4FcUmPXTEwkvcc6hEv1PG9wNIu++MfuuHXhThbOrQz1XAScjmNZ98Igd4FX7smdWGC/1dcUrMg40REjRLdf9rwtyElwPEjmmqIduydID3cre7rCVZdch3QAKufZP73c4Qt2Jq6W/249hah8b7rffw3eMkfiqkIa3hCsYBMZ8bh8ixBzCsliWwtXVJHYyrCflLEDuoVn7/T4yBckvdMCmOOEPHqi1EpCc2C7E7tEd9oso4F9mAlg7CYhB1/d/VRDotj+I5Z7ElrbPPUeD+SjpLZiVpP/osEk8YWisKArQUHo25Ywm1F2uZ+4wwLLFX9WQlu6zw== X-YMail-OSG: bGdXDy8VM1m_IqEZiOCRSGLQewfhRWM8B3gOd9kLCq9fkA.H3VO1k2N75q.Tz7e PQ0iuypZ7kXDg0d1mMomHO_dq4jTEt0zc7kDOJ97n89frQmoj0UiWw8d16MjGPgOq_w5K9I_oHHG jB_epSG1qxk58F.wyYBjQhJuatZtcm_48.zebbp.CmqLAPPt8ObynJ2YeYee5bHdFOMEUPOBiXS6 eFfAH3FuX1q9xoC88kv1TBP64ZH9z5ktzokJxfZhmAS5HS6tRmP4XaRqnIxO5HBhh7FXAUN0Cyhd HpigKidm6X_BJ6l2BMfUb85D5z7dRnaUy7hcZqcxRk3A2BMohNT.TmwTqyaXOMFsFLmRxKYJhP6X rpM9cTgIM21gB1T.2SAtzxmOSlk9_cSL3TOxS_NUQmi9bwTXkubBQqXVodpDHsZ_llJ2NGSuv8oI XYQ96oJKuVWoiAxLimnLMUtSNw_uJa1XS084EFcqf3eqEEG9SDfDU.nrHuf4ft24ZQN_f0kqUCd9 P2hj00CV0upwoC_KFGClPurqSN_YjCCNiyue3X0emCv.mzCVKdfFtFX5DrxlMB9Afgfm2tpTrsOb M.hlG_TcL3wfzHywkvDdnPiOmbDwnyVYWkqEEcM2hKqnKX_UgGesuVf9IZ98hHCjGqZEKPY8W_Ch j6OLgm43CyThWErFWz4L41Pq5wNRTzh3O.pxrWzjjNEht3er19yULIfgFO4LhBIKe2RFuKSHPQIK bmIBMi5XNLruldQbrjyAlXJh4g6tRKJbd2HYiUJQnEE2W8BWxSgJ3h.WzwbFXLAffIDlxs6ME3uc 1JQDlvqwdw9Bl6JqGyZUr6PzWN4h0vxtpzPFrusl4rSu42AF4aLCevvK7marBvbjFD3EeTeMgf4m bF1iexXJtnubN7zYl8_ufXcmfK9F4E.jQ3_VYE0R21taAWP6G1QCR_ROlF54PF.aG9FkyirYe66G xEpiJvI61KNxyD4vk2R3EplH71td2P1xw6rMYyqOVj2cmvjgWLPxThQa3NXa0N4U8QqJezp.zCC1 hIZ7R7Eon.XGK4pI3hz4WSQYabyqWUDhLNKDSwZhv13LTQZ6JxlnaeVzR_w6.lHsE7BHnOFl6rQv CAE5n0Z8isSqR6sVInpQoSSwxQcT90jDb36VWvQU.N8SZAbm7r56c_AyVqBb18racKD9z81Bn_Rt .Jrw1iCv7yGr1e6C4svePaYjkMmXlNh_FVbBqm3WD5SgyYXa8F6SRdM8SvqMHnULhiGg2CdTaS0F jzWdS39ihuK0jSv3gyDHyjXZHnsh6ksLAJF5ncN_ybT9oqRa98wU6zXql1IAzDK0rfYDxUnkt9Tp dTpAk Received: from sonic.gate.mail.ne1.yahoo.com by sonic316.consmr.mail.bf2.yahoo.com with HTTP; Thu, 29 Aug 2019 23:30:13 +0000 Received: by smtp408.mail.bf1.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID 2d799b9799b92d4529ae6bd2b9fbf9fb; Thu, 29 Aug 2019 23:30:11 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, jmorris@namei.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org Cc: casey@schaufler-ca.com, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, paul@paul-moore.com, sds@tycho.nsa.gov Subject: [PATCH v8 19/28] LSM: Use lsmcontext in security_inode_getsecctx Date: Thu, 29 Aug 2019 16:29:26 -0700 Message-Id: <20190829232935.7099-20-casey@schaufler-ca.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190829232935.7099-1-casey@schaufler-ca.com> References: <20190829232935.7099-1-casey@schaufler-ca.com> MIME-Version: 1.0 Sender: selinux-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: selinux@vger.kernel.org Change the security_inode_getsecctx() interface to fill a lsmcontext structure instead of data and length pointers. This provides the information about which LSM created the context so that security_release_secctx() can use the correct hook. A lsmcontext is used within kernfs to store the security information as well. security_inode_getsecctx() does not use the "display" value. There's only one possible user at any time at this point, and the use is only internal. Signed-off-by: Casey Schaufler --- fs/kernfs/dir.c | 9 ++------- fs/kernfs/inode.c | 34 ++++++++++++---------------------- fs/kernfs/kernfs-internal.h | 3 +-- fs/nfsd/nfs4xdr.c | 23 +++++++++-------------- include/linux/security.h | 5 +++-- security/security.c | 13 +++++++++++-- 6 files changed, 38 insertions(+), 49 deletions(-) diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c index c8362b6d556e..1d000289d8b7 100644 --- a/fs/kernfs/dir.c +++ b/fs/kernfs/dir.c @@ -532,13 +532,8 @@ void kernfs_put(struct kernfs_node *kn) kfree_const(kn->name); if (kn->iattr) { - struct lsmcontext scaff; /* scaffolding */ - - if (kn->iattr->ia_secdata) { - lsmcontext_init(&scaff, kn->iattr->ia_secdata, - kn->iattr->ia_secdata_len, 0); - security_release_secctx(&scaff); - } + if (kn->iattr->ia_context.context) + security_release_secctx(&kn->iattr->ia_context); simple_xattrs_free(&kn->iattr->xattrs); kmem_cache_free(kernfs_iattrs_cache, kn->iattr); } diff --git a/fs/kernfs/inode.c b/fs/kernfs/inode.c index 02cde9dac5ee..ffbf7863306d 100644 --- a/fs/kernfs/inode.c +++ b/fs/kernfs/inode.c @@ -135,21 +135,14 @@ int kernfs_iop_setattr(struct dentry *dentry, struct iattr *iattr) return error; } -static int kernfs_node_setsecdata(struct kernfs_iattrs *attrs, void **secdata, - u32 *secdata_len) +static void kernfs_node_setsecdata(struct kernfs_iattrs *attrs, + struct lsmcontext *cp) { - void *old_secdata; - size_t old_secdata_len; + struct lsmcontext old_context; - old_secdata = attrs->ia_secdata; - old_secdata_len = attrs->ia_secdata_len; - - attrs->ia_secdata = *secdata; - attrs->ia_secdata_len = *secdata_len; - - *secdata = old_secdata; - *secdata_len = old_secdata_len; - return 0; + old_context = attrs->ia_context; + attrs->ia_context = *cp; + *cp = old_context; } ssize_t kernfs_iop_listxattr(struct dentry *dentry, char *buf, size_t size) @@ -192,8 +185,8 @@ static void kernfs_refresh_inode(struct kernfs_node *kn, struct inode *inode) * persistent copy in kernfs_node. */ set_inode_attr(inode, &attrs->ia_iattr); - security_inode_notifysecctx(inode, attrs->ia_secdata, - attrs->ia_secdata_len); + security_inode_notifysecctx(inode, attrs->ia_context.context, + attrs->ia_context.len); } if (kernfs_type(kn) == KERNFS_DIR) @@ -350,8 +343,6 @@ static int kernfs_security_xattr_set(const struct xattr_handler *handler, struct kernfs_node *kn = inode->i_private; struct kernfs_iattrs *attrs; struct lsmcontext context; - void *secdata; - u32 secdata_len = 0; int error; attrs = kernfs_iattrs(kn); @@ -361,18 +352,17 @@ static int kernfs_security_xattr_set(const struct xattr_handler *handler, error = security_inode_setsecurity(inode, suffix, value, size, flags); if (error) return error; - error = security_inode_getsecctx(inode, &secdata, &secdata_len); + error = security_inode_getsecctx(inode, &context); if (error) return error; mutex_lock(&kernfs_mutex); - error = kernfs_node_setsecdata(attrs, &secdata, &secdata_len); + kernfs_node_setsecdata(attrs, &context); mutex_unlock(&kernfs_mutex); - if (secdata) { - lsmcontext_init(&context, secdata, secdata_len, 0); + if (context.context) security_release_secctx(&context); - } + return error; } diff --git a/fs/kernfs/kernfs-internal.h b/fs/kernfs/kernfs-internal.h index 0b7d197a904c..844a028d282f 100644 --- a/fs/kernfs/kernfs-internal.h +++ b/fs/kernfs/kernfs-internal.h @@ -21,8 +21,7 @@ struct kernfs_iattrs { struct iattr ia_iattr; - void *ia_secdata; - u32 ia_secdata_len; + struct lsmcontext ia_context; struct simple_xattrs xattrs; }; diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index bb3db033e144..d2dbec9c3340 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -2304,11 +2304,11 @@ nfsd4_encode_layout_types(struct xdr_stream *xdr, u32 layout_types) #ifdef CONFIG_NFSD_V4_SECURITY_LABEL static inline __be32 nfsd4_encode_security_label(struct xdr_stream *xdr, struct svc_rqst *rqstp, - void *context, int len) + struct lsmcontext *context) { __be32 *p; - p = xdr_reserve_space(xdr, len + 4 + 4 + 4); + p = xdr_reserve_space(xdr, context->len + 4 + 4 + 4); if (!p) return nfserr_resource; @@ -2318,13 +2318,13 @@ nfsd4_encode_security_label(struct xdr_stream *xdr, struct svc_rqst *rqstp, */ *p++ = cpu_to_be32(0); /* lfs */ *p++ = cpu_to_be32(0); /* pi */ - p = xdr_encode_opaque(p, context, len); + p = xdr_encode_opaque(p, context->context, context->len); return 0; } #else static inline __be32 nfsd4_encode_security_label(struct xdr_stream *xdr, struct svc_rqst *rqstp, - void *context, int len) + struct lsmcontext *context) { return 0; } #endif @@ -2420,9 +2420,7 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp, __be32 status; int err; struct nfs4_acl *acl = NULL; - struct lsmcontext scaff; /* scaffolding */ - void *context = NULL; - int contextlen; + struct lsmcontext context = { }; bool contextsupport = false; struct nfsd4_compoundres *resp = rqstp->rq_resp; u32 minorversion = resp->cstate.minorversion; @@ -2479,7 +2477,7 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp, bmval0 & FATTR4_WORD0_SUPPORTED_ATTRS) { if (exp->ex_flags & NFSEXP_SECURITY_LABEL) err = security_inode_getsecctx(d_inode(dentry), - &context, &contextlen); + &context); else err = -EOPNOTSUPP; contextsupport = (err == 0); @@ -2908,8 +2906,7 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp, } if (bmval2 & FATTR4_WORD2_SECURITY_LABEL) { - status = nfsd4_encode_security_label(xdr, rqstp, context, - contextlen); + status = nfsd4_encode_security_label(xdr, rqstp, &context); if (status) goto out; } @@ -2920,10 +2917,8 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp, out: #ifdef CONFIG_NFSD_V4_SECURITY_LABEL - if (context) { - lsmcontext_init(&scaff, context, contextlen, 0); /*scaffolding*/ - security_release_secctx(&scaff); - } + if (context.context) + security_release_secctx(&context); #endif /* CONFIG_NFSD_V4_SECURITY_LABEL */ kfree(acl); if (tempfh) { diff --git a/include/linux/security.h b/include/linux/security.h index 2674eb70c2d7..c16aea55be97 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -489,7 +489,7 @@ void security_release_secctx(struct lsmcontext *cp); void security_inode_invalidate_secctx(struct inode *inode); int security_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen); int security_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen); -int security_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen); +int security_inode_getsecctx(struct inode *inode, struct lsmcontext *cp); #else /* CONFIG_SECURITY */ static inline int call_lsm_notifier(enum lsm_event event, void *data) @@ -1290,7 +1290,8 @@ static inline int security_inode_setsecctx(struct dentry *dentry, void *ctx, u32 { return -EOPNOTSUPP; } -static inline int security_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen) +static inline int security_inode_getsecctx(struct inode *inode, + struct lsmcontext *cp) { return -EOPNOTSUPP; } diff --git a/security/security.c b/security/security.c index 7bbc17cc212d..20805ad99ccd 100644 --- a/security/security.c +++ b/security/security.c @@ -2198,9 +2198,18 @@ int security_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen) } EXPORT_SYMBOL(security_inode_setsecctx); -int security_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen) +int security_inode_getsecctx(struct inode *inode, struct lsmcontext *cp) { - return call_int_hook(inode_getsecctx, -EOPNOTSUPP, inode, ctx, ctxlen); + struct security_hook_list *hp; + + memset(cp, 0, sizeof(*cp)); + + hlist_for_each_entry(hp, &security_hook_heads.inode_getsecctx, list) { + cp->slot = hp->lsmid->slot; + return hp->hook.inode_getsecctx(inode, (void **)&cp->context, + &cp->len); + } + return -EOPNOTSUPP; } EXPORT_SYMBOL(security_inode_getsecctx); From patchwork Thu Aug 29 23:29:27 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 11122663 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 0103414E5 for ; Thu, 29 Aug 2019 23:30:21 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id D2DC12189D for ; Thu, 29 Aug 2019 23:30:20 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="KdumSXWV" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728192AbfH2XaU (ORCPT ); Thu, 29 Aug 2019 19:30:20 -0400 Received: from sonic310-28.consmr.mail.gq1.yahoo.com ([98.137.69.154]:43604 "EHLO sonic310-28.consmr.mail.gq1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728295AbfH2XaU (ORCPT ); Thu, 29 Aug 2019 19:30:20 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1567121418; bh=NX1Wm9mZ2rrFAh4r01JvGuFtS1Wfm+5+bHPs+vG06x4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=KdumSXWVnk7MPX/PRbmTBz06UWydkkrc/PubkN6V54WUAwrTNiBUhC2ZJRZlvTv/0LDnctbSqdBj12jYEueRx4IGX4rL/lFc5Lnxiw+JpZrAfQzv7UQg/6ani1T9d59i63HCEUH1k1BLZoSLxymf/jXhJTT5CAdHY91QxSWwMj2x0th7M8PYy7ubPtQHbTHgfjkgR85cMyVy+S43je5n1TuiUyZVgGqUB71FRT1T2mdn3fygdyJQHPW1GgV1CIN5SoH9xj++z8eaIeZwktlw1pGPgEzMtbEt/eiHRi/5H/j1O3Yzome0zRU93uLNCxWhObNYBuimD7+DSYTTAI87Dg== X-YMail-OSG: k1AO6u4VM1l7D_9R77afib1Fxxa67Q6y5YXiOj6DGp2awbebriKHCfxz5zLK3Va hRPp42lDfiZzj6IrUBShGP9anRBtSW.8SGVn_KfFRJi6LzqGQu8amZx10rsT7ZjRVaoF8Nbnsvzb KoiVSBdbdHMZXN5jomiowECr0TVpu4IIghyEprVA2PxFC4ZTcP9m8Sb9ourdBjvGYVmYRXTwTXZa RakBzmdusWqKaOlVnwKQYMAB1ISHwfLxAV6CoEBB2VONiYJYcAzkP0h8VvO2nyrHq33QiyVvBOyp N68ZcCxEyAZlC1VEqQzSlSa1Bf6p289.uzYGhchChO3IHdgOehzFiel6.mXs53jVhXTlO1iXg908 JXu0XnfB.DGBmBqgABoFULjhuEoEXZ8XkSGjatM2ttuKAPljXsdjRya2tDuelY.0ulCjicy2s4Hv jQtmMvdq1o00cFzq1D_SKDklFiLbIAeMPmrFzq58UNBScq7VdbUV0xwUBcZ.6yeyIE0kT0FykKsY CyfWKwC6wNnMZ81PYEdy.BgjAapbeeocD.gFrWMBtaE_wAkiiQTP4b3ZCVVN3E8P98p4Qi9pU4ZW Bbyd5qMXgiUgUor1h95gt_Y47cQ5HvwQo1YWe_VAWbo7NZQ.PDDpfRxx6jSSCaTcJNtZGV6XG0IA XdCznwoGaxieQsl4BDgLL4xhTNL9gCBBL.KtJnoD.5XrjQEVYCB9F.HiP_rqYZIamcvdOUjt_BQq lUMoo68bSCbvGqQHU95EbjAUvjmlr0gNc3LjiwEQy55j_UPu5huA4Ol6iSqPc9DH5vyYZPJHW30S REgwFzD99L3rmVmnIwG6Q5Ffb.MJl8px8qLHyVLDppNcUN72vHY5B2oqueTYStL6yhYTXKif8hUj IBl0mIwBa6S2c49bufnRy.uFXUfTOWX0zkrD2xcde3t08eZ91ixNicz_p9e062qYAtSh1lsk8zBA Q3gvGlYJ2tl9NoznAJlz_od5eSAXS4r.L..F1Rijen5ig__SzCLGj9ZnNQU_1bqBwITdA_Fb7gEZ CLCGVAi3Ln_763Tq3ey8ywD9t0rvf5hT_y2zaTZcCZYst_7C5hXQdQ9tyJMAfxBzHFQDMuXFJQ45 MV9kQ6FHeR6WxSCjUL.ZcucXfP4Dc6dS08f1BoYJeHHcnzG02JvA530zVc.3nslCS9VFVy2r8WOX Om.1WlYqS9xFSl8tq3TgCYGpNddCJeUheNtuw3Tgdpm7AT8F8cz2jEBZlAhWgul0u.hHLe8sTwdc dQLDIWFIASR9.rqxE5UvOBxUywQug0I.9pSbTFZKjl8B_CLp2IPe_snxF23Bc6us4mZdlw2htdMZ 18mAS Received: from sonic.gate.mail.ne1.yahoo.com by sonic310.consmr.mail.gq1.yahoo.com with HTTP; Thu, 29 Aug 2019 23:30:18 +0000 Received: by smtp402.mail.gq1.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID f8639e220c8a96cf24b2b0474e56d17f; Thu, 29 Aug 2019 23:30:14 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, jmorris@namei.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org Cc: casey@schaufler-ca.com, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, paul@paul-moore.com, sds@tycho.nsa.gov Subject: [PATCH v8 20/28] LSM: security_secid_to_secctx in netlink netfilter Date: Thu, 29 Aug 2019 16:29:27 -0700 Message-Id: <20190829232935.7099-21-casey@schaufler-ca.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190829232935.7099-1-casey@schaufler-ca.com> References: <20190829232935.7099-1-casey@schaufler-ca.com> MIME-Version: 1.0 Sender: selinux-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: selinux@vger.kernel.org Change netlink netfilter interfaces to use lsmcontext pointers, and remove scaffolding. Reviewed-by: Kees Cook Reviewed-by: John Johansen Signed-off-by: Casey Schaufler --- net/netfilter/nfnetlink_queue.c | 32 +++++++++++++------------------- 1 file changed, 13 insertions(+), 19 deletions(-) diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c index 5593ee05d106..58d5bd7a376e 100644 --- a/net/netfilter/nfnetlink_queue.c +++ b/net/netfilter/nfnetlink_queue.c @@ -305,12 +305,10 @@ static int nfqnl_put_sk_uidgid(struct sk_buff *skb, struct sock *sk) return -1; } -static u32 nfqnl_get_sk_secctx(struct sk_buff *skb, char **secdata) +static u32 nfqnl_get_sk_secctx(struct sk_buff *skb, struct lsmcontext *context) { - u32 seclen = 0; #if IS_ENABLED(CONFIG_NETWORK_SECMARK) struct lsmblob blob; - struct lsmcontext context = { }; if (!skb || !sk_fullsock(skb->sk)) return 0; @@ -318,15 +316,16 @@ static u32 nfqnl_get_sk_secctx(struct sk_buff *skb, char **secdata) read_lock_bh(&skb->sk->sk_callback_lock); if (skb->secmark) { + /* Any LSM might be looking for the secmark */ lsmblob_init(&blob, skb->secmark); - security_secid_to_secctx(&blob, &context); - *secdata = context.context; + security_secid_to_secctx(&blob, context); } read_unlock_bh(&skb->sk->sk_callback_lock); - seclen = context.len; + return context->len; +#else + return 0; #endif - return seclen; } static u32 nfqnl_get_bridge_size(struct nf_queue_entry *entry) @@ -402,8 +401,7 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue, enum ip_conntrack_info uninitialized_var(ctinfo); struct nfnl_ct_hook *nfnl_ct; bool csum_verify; - struct lsmcontext scaff; /* scaffolding */ - char *secdata = NULL; + struct lsmcontext context = { }; u32 seclen = 0; size = nlmsg_total_size(sizeof(struct nfgenmsg)) @@ -470,7 +468,7 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue, } if ((queue->flags & NFQA_CFG_F_SECCTX) && entskb->sk) { - seclen = nfqnl_get_sk_secctx(entskb, &secdata); + seclen = nfqnl_get_sk_secctx(entskb, &context); if (seclen) size += nla_total_size(seclen); } @@ -605,7 +603,7 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue, nfqnl_put_sk_uidgid(skb, entskb->sk) < 0) goto nla_put_failure; - if (seclen && nla_put(skb, NFQA_SECCTX, seclen, secdata)) + if (seclen && nla_put(skb, NFQA_SECCTX, context.len, context.context)) goto nla_put_failure; if (ct && nfnl_ct->build(skb, ct, ctinfo, NFQA_CT, NFQA_CT_INFO) < 0) @@ -633,10 +631,8 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue, } nlh->nlmsg_len = skb->len; - if (seclen) { - lsmcontext_init(&scaff, secdata, seclen, 0); - security_release_secctx(&scaff); - } + if (seclen) + security_release_secctx(&context); return skb; nla_put_failure: @@ -644,10 +640,8 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue, kfree_skb(skb); net_err_ratelimited("nf_queue: error creating packet message\n"); nlmsg_failure: - if (seclen) { - lsmcontext_init(&scaff, secdata, seclen, 0); - security_release_secctx(&scaff); - } + if (seclen) + security_release_secctx(&context); return NULL; } From patchwork Thu Aug 29 23:29:28 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 11122667 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 410F014E5 for ; Thu, 29 Aug 2019 23:30:22 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 0C7F521874 for ; Thu, 29 Aug 2019 23:30:22 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="QT+4fRd9" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726036AbfH2XaV (ORCPT ); Thu, 29 Aug 2019 19:30:21 -0400 Received: from sonic310-28.consmr.mail.gq1.yahoo.com ([98.137.69.154]:42028 "EHLO sonic310-28.consmr.mail.gq1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728262AbfH2XaU (ORCPT ); Thu, 29 Aug 2019 19:30:20 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1567121418; bh=QBHfVDraTJfyQsXmvPbQZscdLlVRq9swZuy/DIgAlxo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=QT+4fRd9IaloPT3vsrY28q6m2ToH/ntA+7XJ4OBBbVY0fSd7pK3qBWgcGO6eNg4GLyKpKlZnU03Me9u9NgOb9oHE9MTNPwrtrSY4H5Aa1tUeS/54DO/NvOmX+8VGgpzjnTpf10PBHRrqVx1+c3rw0CDySdirpx7Dv+CAKkun7Ma6qcMymv9K/ye+3gOmWoQVpv7aCXzC4xbicUINjibx/ptTBsIuFLvVIOpmecU/u2EVyU+kKzZ3ZGgjxAxhZo6Qt6++hzVX4mG1HvpATS63hjdDhbVNTErpItdCXI4istaLDEHET5ytV7yKTQqL8PGBF+bgNKDQdJ9bd6R1zIQEvQ== X-YMail-OSG: 8amy1cgVM1l7UJesf0.wrXNu74EtNvFYy4Ct1awm78EOEFzdyvez9BkBR44vXHZ RbHBUQoHA47aSGYJEZXfNnpKPEr_T1RBbv_ECgADN8_mKuUhyl6jhQEJMrKKfwVbdWjT5Nqi5t7k mN31aI8saCDiuVJPi_oH3DkR5Oj51UuAXKv9SMrVHCWcicmGyAzR74jGRGGP5UGTY2BFIJ2j9gEI GjbR9e2GOdiDGYtNdJf_1CbopouVj4Kb.HqwLQJxR8itICBenIY5QEszGp71vcB8R2pQE0lG0xsf Y.77fQ4TQiZ3aySFm.TYlIQPs5.CPDczBHT0YcqUAmtgzX1gVbSOwQab4c4_oy5TMgOp4N3u6SUQ 3_0K42yJPE0oyEIruN2ZOf8qS4Gi1J.Nlu6L30Vb9kuMlcqr9YYqN5PSVzuVWK336xSKX.F5UBPz ro0bcPSW4muFCxOfQ.18vwIna39K3pLwRisWRrcU41r1DimeCI_4XMF5E1b1XjxJrlO5pnTMXzDM NA6DnPuSNvBIUddJuAQbtRN2rbziuTRuBZha1VwOkOPmiewUpEztOaWBd49_FaKFUkkpmmW2__4F NjDj5dG.f9YWbni2Nmi6e65133w85QB0totxZJwiPsrZSNDDOAEcSCJx3r5aqPWTOa9rjz7GbA9x X5964LP7qwiLqMiQrr6S1Jp7rjeFhVA8CMHe9MD0EWo32lZCI.61DB3Zf3QjHJaRuBq7gfdDtokD mWWkP_3VXkRL36t5SRkOYTUQCODsP3fuz3dGE7lqnrk_6YlbFA8B0vAsi4RpTHFlJpk9ermu0xYy cP47DtH_6AXe76WPcX3otPtvNt_fbDkU6a_.nfOZKMO.WQJD1v9q7qfvAacnMhJd4lK6.TEwRGF0 q3okTNwNI1VEgZdpg4I8uluBSpjPz.0SUmdF2yz6kTSWqLLR.MlV2U9PrvZuEXPYQOW.2jCIISiI Q5Wqj6ltZIp2.DaxL.D73sneXEsqZtcRit0Jxji2pDdqhIZys6WAwZA6syY7PVlv4B59axSoYOa0 b3hNP3ftMGPxj69HqQF.FTqMjlU02GOpHwVS10paCXeqCELy1W5Ka8kmOL7spvsYNBVlldoyoEp3 XzWhfDKvqC8r9F08.oa2K5x2YVvvcTk2Qkyhithke_lny_F5T_0l32g7t6qlgFkF0t2FIlAFaKmy BsdWN10ZpzkcdpyAOW7doFvof.Atcgn0nHqYVryuEzfqBItXC_EGyJ0kM4dqKREXbqrzoDEpru.n kaF.nJZeY8mbop1XRGUqN000E5tLLaaurSA.sHQtz6I7jzd1O6WV1GHH8o0DSm4cc3o.ywL6xA0B ZGoNUsm9zmg-- Received: from sonic.gate.mail.ne1.yahoo.com by sonic310.consmr.mail.gq1.yahoo.com with HTTP; Thu, 29 Aug 2019 23:30:18 +0000 Received: by smtp402.mail.gq1.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID f8639e220c8a96cf24b2b0474e56d17f; Thu, 29 Aug 2019 23:30:15 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, jmorris@namei.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org Cc: casey@schaufler-ca.com, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, paul@paul-moore.com, sds@tycho.nsa.gov Subject: [PATCH v8 21/28] NET: Store LSM netlabel data in a lsmblob Date: Thu, 29 Aug 2019 16:29:28 -0700 Message-Id: <20190829232935.7099-22-casey@schaufler-ca.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190829232935.7099-1-casey@schaufler-ca.com> References: <20190829232935.7099-1-casey@schaufler-ca.com> MIME-Version: 1.0 Sender: selinux-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: selinux@vger.kernel.org Netlabel uses LSM interfaces requiring an lsmblob and the internal storage is used to pass information between these interfaces, so change the internal data from a secid to a lsmblob. Update the netlabel interfaces and their callers to accommodate the change. This requires that the modules using netlabel use the lsm_id.slot to access the correct secid when using netlabel. Reviewed-by: Kees Cook Reviewed-by: John Johansen Signed-off-by: Casey Schaufler --- include/net/netlabel.h | 8 ++-- net/ipv4/cipso_ipv4.c | 6 ++- net/netlabel/netlabel_kapi.c | 6 +-- net/netlabel/netlabel_unlabeled.c | 57 +++++++++++------------------ net/netlabel/netlabel_unlabeled.h | 2 +- security/selinux/hooks.c | 2 +- security/selinux/include/security.h | 1 + security/selinux/netlabel.c | 2 +- security/selinux/ss/services.c | 4 +- security/smack/smack.h | 1 + security/smack/smack_lsm.c | 5 ++- security/smack/smackfs.c | 10 +++-- 12 files changed, 50 insertions(+), 54 deletions(-) diff --git a/include/net/netlabel.h b/include/net/netlabel.h index 72d6435fc16c..6c550455e69f 100644 --- a/include/net/netlabel.h +++ b/include/net/netlabel.h @@ -180,7 +180,7 @@ struct netlbl_lsm_catmap { * @attr.mls: MLS sensitivity label * @attr.mls.cat: MLS category bitmap * @attr.mls.lvl: MLS sensitivity level - * @attr.secid: LSM specific secid token + * @attr.lsmblob: LSM specific data * * Description: * This structure is used to pass security attributes between NetLabel and the @@ -215,7 +215,7 @@ struct netlbl_lsm_secattr { struct netlbl_lsm_catmap *cat; u32 lvl; } mls; - u32 secid; + struct lsmblob lsmblob; } attr; }; @@ -429,7 +429,7 @@ int netlbl_cfg_unlbl_static_add(struct net *net, const void *addr, const void *mask, u16 family, - u32 secid, + struct lsmblob *lsmblob, struct netlbl_audit *audit_info); int netlbl_cfg_unlbl_static_del(struct net *net, const char *dev_name, @@ -537,7 +537,7 @@ static inline int netlbl_cfg_unlbl_static_add(struct net *net, const void *addr, const void *mask, u16 family, - u32 secid, + struct lsmblob *lsmblob, struct netlbl_audit *audit_info) { return -ENOSYS; diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c index f0165c5f376b..eb4939f38a14 100644 --- a/net/ipv4/cipso_ipv4.c +++ b/net/ipv4/cipso_ipv4.c @@ -1481,7 +1481,8 @@ static int cipso_v4_gentag_loc(const struct cipso_v4_doi *doi_def, buffer[0] = CIPSO_V4_TAG_LOCAL; buffer[1] = CIPSO_V4_TAG_LOC_BLEN; - *(u32 *)&buffer[2] = secattr->attr.secid; + /* only one netlabel user - the first */ + *(u32 *)&buffer[2] = secattr->attr.lsmblob.secid[0]; return CIPSO_V4_TAG_LOC_BLEN; } @@ -1501,7 +1502,8 @@ static int cipso_v4_parsetag_loc(const struct cipso_v4_doi *doi_def, const unsigned char *tag, struct netlbl_lsm_secattr *secattr) { - secattr->attr.secid = *(u32 *)&tag[2]; + /* only one netlabel user - the first */ + secattr->attr.lsmblob.secid[0] = *(u32 *)&tag[2]; secattr->flags |= NETLBL_SECATTR_SECID; return 0; diff --git a/net/netlabel/netlabel_kapi.c b/net/netlabel/netlabel_kapi.c index ee3e5b6471a6..724d44943543 100644 --- a/net/netlabel/netlabel_kapi.c +++ b/net/netlabel/netlabel_kapi.c @@ -210,7 +210,7 @@ int netlbl_cfg_unlbl_map_add(const char *domain, * @addr: IP address in network byte order (struct in[6]_addr) * @mask: address mask in network byte order (struct in[6]_addr) * @family: address family - * @secid: LSM secid value for the entry + * @lsmblob: LSM data value for the entry * @audit_info: NetLabel audit information * * Description: @@ -224,7 +224,7 @@ int netlbl_cfg_unlbl_static_add(struct net *net, const void *addr, const void *mask, u16 family, - u32 secid, + struct lsmblob *lsmblob, struct netlbl_audit *audit_info) { u32 addr_len; @@ -244,7 +244,7 @@ int netlbl_cfg_unlbl_static_add(struct net *net, return netlbl_unlhsh_add(net, dev_name, addr, mask, addr_len, - secid, audit_info); + lsmblob, audit_info); } /** diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c index 4716e0011ba5..57ede7781c8f 100644 --- a/net/netlabel/netlabel_unlabeled.c +++ b/net/netlabel/netlabel_unlabeled.c @@ -80,7 +80,7 @@ struct netlbl_unlhsh_tbl { #define netlbl_unlhsh_addr4_entry(iter) \ container_of(iter, struct netlbl_unlhsh_addr4, list) struct netlbl_unlhsh_addr4 { - u32 secid; + struct lsmblob lsmblob; struct netlbl_af4list list; struct rcu_head rcu; @@ -88,7 +88,7 @@ struct netlbl_unlhsh_addr4 { #define netlbl_unlhsh_addr6_entry(iter) \ container_of(iter, struct netlbl_unlhsh_addr6, list) struct netlbl_unlhsh_addr6 { - u32 secid; + struct lsmblob lsmblob; struct netlbl_af6list list; struct rcu_head rcu; @@ -233,7 +233,7 @@ static struct netlbl_unlhsh_iface *netlbl_unlhsh_search_iface(int ifindex) * @iface: the associated interface entry * @addr: IPv4 address in network byte order * @mask: IPv4 address mask in network byte order - * @secid: LSM secid value for entry + * @lsmblob: LSM data value for entry * * Description: * Add a new address entry into the unlabeled connection hash table using the @@ -244,7 +244,7 @@ static struct netlbl_unlhsh_iface *netlbl_unlhsh_search_iface(int ifindex) static int netlbl_unlhsh_add_addr4(struct netlbl_unlhsh_iface *iface, const struct in_addr *addr, const struct in_addr *mask, - u32 secid) + struct lsmblob *lsmblob) { int ret_val; struct netlbl_unlhsh_addr4 *entry; @@ -256,7 +256,7 @@ static int netlbl_unlhsh_add_addr4(struct netlbl_unlhsh_iface *iface, entry->list.addr = addr->s_addr & mask->s_addr; entry->list.mask = mask->s_addr; entry->list.valid = 1; - entry->secid = secid; + entry->lsmblob = *lsmblob; spin_lock(&netlbl_unlhsh_lock); ret_val = netlbl_af4list_add(&entry->list, &iface->addr4_list); @@ -273,7 +273,7 @@ static int netlbl_unlhsh_add_addr4(struct netlbl_unlhsh_iface *iface, * @iface: the associated interface entry * @addr: IPv6 address in network byte order * @mask: IPv6 address mask in network byte order - * @secid: LSM secid value for entry + * @lsmblob: LSM data value for entry * * Description: * Add a new address entry into the unlabeled connection hash table using the @@ -284,7 +284,7 @@ static int netlbl_unlhsh_add_addr4(struct netlbl_unlhsh_iface *iface, static int netlbl_unlhsh_add_addr6(struct netlbl_unlhsh_iface *iface, const struct in6_addr *addr, const struct in6_addr *mask, - u32 secid) + struct lsmblob *lsmblob) { int ret_val; struct netlbl_unlhsh_addr6 *entry; @@ -300,7 +300,7 @@ static int netlbl_unlhsh_add_addr6(struct netlbl_unlhsh_iface *iface, entry->list.addr.s6_addr32[3] &= mask->s6_addr32[3]; entry->list.mask = *mask; entry->list.valid = 1; - entry->secid = secid; + entry->lsmblob = *lsmblob; spin_lock(&netlbl_unlhsh_lock); ret_val = netlbl_af6list_add(&entry->list, &iface->addr6_list); @@ -379,7 +379,7 @@ int netlbl_unlhsh_add(struct net *net, const void *addr, const void *mask, u32 addr_len, - u32 secid, + struct lsmblob *lsmblob, struct netlbl_audit *audit_info) { int ret_val; @@ -388,7 +388,6 @@ int netlbl_unlhsh_add(struct net *net, struct netlbl_unlhsh_iface *iface; struct audit_buffer *audit_buf = NULL; struct lsmcontext context; - struct lsmblob blob; if (addr_len != sizeof(struct in_addr) && addr_len != sizeof(struct in6_addr)) @@ -421,7 +420,7 @@ int netlbl_unlhsh_add(struct net *net, const struct in_addr *addr4 = addr; const struct in_addr *mask4 = mask; - ret_val = netlbl_unlhsh_add_addr4(iface, addr4, mask4, secid); + ret_val = netlbl_unlhsh_add_addr4(iface, addr4, mask4, lsmblob); if (audit_buf != NULL) netlbl_af4list_audit_addr(audit_buf, 1, dev_name, @@ -434,7 +433,7 @@ int netlbl_unlhsh_add(struct net *net, const struct in6_addr *addr6 = addr; const struct in6_addr *mask6 = mask; - ret_val = netlbl_unlhsh_add_addr6(iface, addr6, mask6, secid); + ret_val = netlbl_unlhsh_add_addr6(iface, addr6, mask6, lsmblob); if (audit_buf != NULL) netlbl_af6list_audit_addr(audit_buf, 1, dev_name, @@ -451,8 +450,7 @@ int netlbl_unlhsh_add(struct net *net, unlhsh_add_return: rcu_read_unlock(); if (audit_buf != NULL) { - lsmblob_init(&blob, secid); - if (security_secid_to_secctx(&blob, &context) == 0) { + if (security_secid_to_secctx(lsmblob, &context) == 0) { audit_log_format(audit_buf, " sec_obj=%s", context.context); security_release_secctx(&context); @@ -487,7 +485,6 @@ static int netlbl_unlhsh_remove_addr4(struct net *net, struct audit_buffer *audit_buf; struct net_device *dev; struct lsmcontext context; - struct lsmblob blob; spin_lock(&netlbl_unlhsh_lock); list_entry = netlbl_af4list_remove(addr->s_addr, mask->s_addr, @@ -507,10 +504,8 @@ static int netlbl_unlhsh_remove_addr4(struct net *net, addr->s_addr, mask->s_addr); if (dev != NULL) dev_put(dev); - if (entry != NULL) - lsmblob_init(&blob, entry->secid); if (entry != NULL && - security_secid_to_secctx(&blob, &context) == 0) { + security_secid_to_secctx(&entry->lsmblob, &context) == 0) { audit_log_format(audit_buf, " sec_obj=%s", context.context); security_release_secctx(&context); @@ -551,7 +546,6 @@ static int netlbl_unlhsh_remove_addr6(struct net *net, struct audit_buffer *audit_buf; struct net_device *dev; struct lsmcontext context; - struct lsmblob blob; spin_lock(&netlbl_unlhsh_lock); list_entry = netlbl_af6list_remove(addr, mask, &iface->addr6_list); @@ -570,10 +564,8 @@ static int netlbl_unlhsh_remove_addr6(struct net *net, addr, mask); if (dev != NULL) dev_put(dev); - if (entry != NULL) - lsmblob_init(&blob, entry->secid); if (entry != NULL && - security_secid_to_secctx(&blob, &context) == 0) { + security_secid_to_secctx(&entry->lsmblob, &context) == 0) { audit_log_format(audit_buf, " sec_obj=%s", context.context); security_release_secctx(&context); @@ -927,9 +919,8 @@ static int netlbl_unlabel_staticadd(struct sk_buff *skb, if (ret_val != 0) return ret_val; - /* scaffolding with the [0] */ return netlbl_unlhsh_add(&init_net, - dev_name, addr, mask, addr_len, blob.secid[0], + dev_name, addr, mask, addr_len, &blob, &audit_info); } @@ -977,10 +968,8 @@ static int netlbl_unlabel_staticadddef(struct sk_buff *skb, if (ret_val != 0) return ret_val; - /* scaffolding with the [0] */ return netlbl_unlhsh_add(&init_net, - NULL, addr, mask, addr_len, blob.secid[0], - &audit_info); + NULL, addr, mask, addr_len, &blob, &audit_info); } /** @@ -1092,8 +1081,7 @@ static int netlbl_unlabel_staticlist_gen(u32 cmd, struct net_device *dev; struct lsmcontext context; void *data; - u32 secid; - struct lsmblob blob; + struct lsmblob *lsmb; data = genlmsg_put(cb_arg->skb, NETLINK_CB(cb_arg->nl_cb->skb).portid, cb_arg->seq, &netlbl_unlabel_gnl_family, @@ -1131,7 +1119,7 @@ static int netlbl_unlabel_staticlist_gen(u32 cmd, if (ret_val != 0) goto list_cb_failure; - secid = addr4->secid; + lsmb = (struct lsmblob *)&addr4->lsmblob; } else { ret_val = nla_put_in6_addr(cb_arg->skb, NLBL_UNLABEL_A_IPV6ADDR, @@ -1145,11 +1133,10 @@ static int netlbl_unlabel_staticlist_gen(u32 cmd, if (ret_val != 0) goto list_cb_failure; - secid = addr6->secid; + lsmb = (struct lsmblob *)&addr6->lsmblob; } - lsmblob_init(&blob, secid); - ret_val = security_secid_to_secctx(&blob, &context); + ret_val = security_secid_to_secctx(lsmb, &context); if (ret_val != 0) goto list_cb_failure; ret_val = nla_put(cb_arg->skb, @@ -1500,7 +1487,7 @@ int netlbl_unlabel_getattr(const struct sk_buff *skb, &iface->addr4_list); if (addr4 == NULL) goto unlabel_getattr_nolabel; - secattr->attr.secid = netlbl_unlhsh_addr4_entry(addr4)->secid; + secattr->attr.lsmblob = netlbl_unlhsh_addr4_entry(addr4)->lsmblob; break; } #if IS_ENABLED(CONFIG_IPV6) @@ -1513,7 +1500,7 @@ int netlbl_unlabel_getattr(const struct sk_buff *skb, &iface->addr6_list); if (addr6 == NULL) goto unlabel_getattr_nolabel; - secattr->attr.secid = netlbl_unlhsh_addr6_entry(addr6)->secid; + secattr->attr.lsmblob = netlbl_unlhsh_addr6_entry(addr6)->lsmblob; break; } #endif /* IPv6 */ diff --git a/net/netlabel/netlabel_unlabeled.h b/net/netlabel/netlabel_unlabeled.h index 3a9e5dc9511b..dcff99695c97 100644 --- a/net/netlabel/netlabel_unlabeled.h +++ b/net/netlabel/netlabel_unlabeled.h @@ -225,7 +225,7 @@ int netlbl_unlhsh_add(struct net *net, const void *addr, const void *mask, u32 addr_len, - u32 secid, + struct lsmblob *lsmblob, struct netlbl_audit *audit_info); int netlbl_unlhsh_remove(struct net *net, const char *dev_name, diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 74c491980ed2..352be16a887d 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -6622,7 +6622,7 @@ struct lsm_blob_sizes selinux_blob_sizes __lsm_ro_after_init = { .lbs_superblock = sizeof(struct superblock_security_struct), }; -static struct lsm_id selinux_lsmid __lsm_ro_after_init = { +struct lsm_id selinux_lsmid __lsm_ro_after_init = { .lsm = "selinux", .slot = LSMBLOB_NEEDED }; diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h index b5b7c5aade8c..f0ca3879ba48 100644 --- a/security/selinux/include/security.h +++ b/security/selinux/include/security.h @@ -68,6 +68,7 @@ struct netlbl_lsm_secattr; extern int selinux_enabled; +extern struct lsm_id selinux_lsmid; /* Policy capabilities */ enum { diff --git a/security/selinux/netlabel.c b/security/selinux/netlabel.c index c40914a157b7..120d50c1bcac 100644 --- a/security/selinux/netlabel.c +++ b/security/selinux/netlabel.c @@ -122,7 +122,7 @@ static struct netlbl_lsm_secattr *selinux_netlbl_sock_getattr( return NULL; if ((secattr->flags & NETLBL_SECATTR_SECID) && - (secattr->attr.secid == sid)) + (secattr->attr.lsmblob.secid[selinux_lsmid.slot] == sid)) return secattr; return NULL; diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index e3f5d6aece66..4ca0e006c3cc 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c @@ -3593,7 +3593,7 @@ int security_netlbl_secattr_to_sid(struct selinux_state *state, if (secattr->flags & NETLBL_SECATTR_CACHE) *sid = *(u32 *)secattr->cache->data; else if (secattr->flags & NETLBL_SECATTR_SECID) - *sid = secattr->attr.secid; + *sid = secattr->attr.lsmblob.secid[selinux_lsmid.slot]; else if (secattr->flags & NETLBL_SECATTR_MLS_LVL) { rc = -EIDRM; ctx = sidtab_search(sidtab, SECINITSID_NETMSG); @@ -3666,7 +3666,7 @@ int security_netlbl_sid_to_secattr(struct selinux_state *state, if (secattr->domain == NULL) goto out; - secattr->attr.secid = sid; + secattr->attr.lsmblob.secid[selinux_lsmid.slot] = sid; secattr->flags |= NETLBL_SECATTR_DOMAIN_CPY | NETLBL_SECATTR_SECID; mls_export_netlbl_lvl(policydb, ctx, secattr); rc = mls_export_netlbl_cat(policydb, ctx, secattr); diff --git a/security/smack/smack.h b/security/smack/smack.h index 7cc3a3382fee..039bf5de56b4 100644 --- a/security/smack/smack.h +++ b/security/smack/smack.h @@ -320,6 +320,7 @@ void smk_destroy_label_list(struct list_head *list); * Shared data. */ extern int smack_enabled; +extern struct lsm_id smack_lsmid; extern int smack_cipso_direct; extern int smack_cipso_mapped; extern struct smack_known *smack_net_ambient; diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index 472cb2097d36..7a30b8692b1e 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -3741,7 +3741,8 @@ static struct smack_known *smack_from_secattr(struct netlbl_lsm_secattr *sap, /* * Looks like a fallback, which gives us a secid. */ - return smack_from_secid(sap->attr.secid); + return smack_from_secid( + sap->attr.lsmblob.secid[smack_lsmid.slot]); /* * Without guidance regarding the smack value * for the packet fall back on the network @@ -4558,7 +4559,7 @@ struct lsm_blob_sizes smack_blob_sizes __lsm_ro_after_init = { .lbs_superblock = sizeof(struct superblock_smack), }; -static struct lsm_id smack_lsmid __lsm_ro_after_init = { +struct lsm_id smack_lsmid __lsm_ro_after_init = { .lsm = "smack", .slot = LSMBLOB_NEEDED }; diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c index faf2ea3968b3..6a4c468c200c 100644 --- a/security/smack/smackfs.c +++ b/security/smack/smackfs.c @@ -1150,6 +1150,7 @@ static void smk_net4addr_insert(struct smk_net4addr *new) static ssize_t smk_write_net4addr(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { + struct lsmblob lsmblob; struct smk_net4addr *snp; struct sockaddr_in newname; char *smack; @@ -1281,10 +1282,13 @@ static ssize_t smk_write_net4addr(struct file *file, const char __user *buf, * this host so that incoming packets get labeled. * but only if we didn't get the special CIPSO option */ - if (rc == 0 && skp != NULL) + if (rc == 0 && skp != NULL) { + lsmblob_init(&lsmblob, 0); + lsmblob.secid[smack_lsmid.slot] = snp->smk_label->smk_secid; rc = netlbl_cfg_unlbl_static_add(&init_net, NULL, - &snp->smk_host, &snp->smk_mask, PF_INET, - snp->smk_label->smk_secid, &audit_info); + &snp->smk_host, &snp->smk_mask, PF_INET, &lsmblob, + &audit_info); + } if (rc == 0) rc = count; From patchwork Thu Aug 29 23:29:29 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 11122659 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 4F72014E5 for ; Thu, 29 Aug 2019 23:30:19 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 297452189D for ; Thu, 29 Aug 2019 23:30:19 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="PB5Oojsq" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727171AbfH2XaS (ORCPT ); Thu, 29 Aug 2019 19:30:18 -0400 Received: from sonic312-30.consmr.mail.gq1.yahoo.com ([98.137.69.211]:39018 "EHLO sonic312-30.consmr.mail.gq1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728262AbfH2XaS (ORCPT ); Thu, 29 Aug 2019 19:30:18 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1567121417; bh=VuF+R1SSIeu+9VfIQQL5nQZN69AkuS8IP6jyAKY1P6I=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=PB5OojsqoBlN4MkA09ncNyc/7fSOxYAOtzGHUZLabbcN/fqmyKt/GUnBG+KHSi16MfTO5hL3Sc4D3O9g0FIMypWqCrA+AifjXD3zZgFuctdHFlhiS1Hk7/idMAyjcx3rWvRnuJ90QV7yQfexlDSONvdnH4dREGZ2W2SmzuiqeZwOsYz94bDyOFo1I7lPm9aI4Z74u6u+2JOxLSP3oC8F1F9epjOgmxOBQxX8FsL577lIJ/w5GAgYuusLjGFnaM4BRSX2vlGNV7lH99H6G0cRHwzeFk2vnsz8FuEbs69GpaPWSd8McjxBcbcaHkjiTQws/W17LgKgDPSCsQQ399sGpw== X-YMail-OSG: wDCVl.kVM1nlmjYO7JxxWg3wKl_t.IqtfpMPhJn6GTIWOtOxTw7tCkkUbMCGuD2 XYjUU1szFFQpIOPkZtnpL0NgixQ8r4F6V2qkelQ11Ak65aGgQUNiA9phcGKisVKE2GvGJDwSOkB3 e8fep4Nz2qyqlc1Fcwyrg2yDN2UMQONH7MChepRhPM91jzHfpXaf7UB8VoOtb.VkDdG90geqlWQM QTGgBDZH1jX1iKOgJhNl.TYXEGi0T_0FcejW.eJ9xzeUtzwBBkxj4p_enwm1CqjJu35dIRIOjeQK 4JBlyE4f8tOOPORDdze7gNms68BDcfwb.oCP5HHFX_CvEAfyqTVFReIrD6W3wbyZPFKxjYCV545T 5XdvVaEtdPGj3sDqls5AK1VAprG83NVK9hs2llN58Ma1GqfjfLtYV03EkW83O40yFyDVytAtWkv8 BCtxNKBIoLve5hdU.E__uclGKz_An5Bg8mrmyP04zbsmMHD.Jeng.GRQUhLeUwJC2c3.tti0iEc5 MZwDZNaj8MlAMkWUUENak.XqaD5w3Ol2zZDt4SkxfdedHVnAMAdLEDojeENuLMv7cyvwnL5HTbPH URlJgvmv4lauCiP729Ih.FDSzh60M6hlW6sdjdv6auNkkANVL7RFfHg0WR7alGV0sHH9.GQ1pMzQ xsiJuTR1RImqiig0sTRDt8BfEaOA9XdAd3IEhrmlYcNQPvtwQmI7Ks3EPz7BwJJH42ab5yEau173 Il1Vib9prDBgKnREW2zBVnyPI1D5LOhQx9aLQywAZEtZ3IN5fCL4BboOFTuQCjtEGcTZ8s9ppMYH 22X.tSvqEUB22jpeiTXWDpUEYm7RiUWRyQWzXH6PeIB1uYsTxSradVmjIYulwiuE1PqsZPpVlyMG ONBEI5BRIevx93XNAitQMX_OlB49ChuFejau5lPbDL3L5urWUIM0DEMDVbYRDcexcffQsCxCtxOy GBzmuk2Au4JTjk3r8zz8J90_v_9.Hi8saOtHX8DqccJY1lL7pFv3wSnijM1fAVwy17EXeMvNipdr vl4q8J5.RIkROFjWH3z7240vXC3yCDkayqRXKzfsDI41Ytzlq_LEc.Iny9R2G9brqAaFvwdbL.TT n0Js2ODf1Ghv1jpfgTius8DSw2dB9Ye3WzT80U9jVNhRwwyLrm4bkjMshxXTSc1d.SZKoWtf1T6J ZXC05Vf1b4Lx4IsdXlgBacbIbmvENmMh9uiGR_wumNMnEvjqnB4.vU4agugN2KT.ld1C0zA3Bxxs tUW5Z6Q2kbC1VeySIejv05z7MOrRppRbxn5zOH.b0qSDqTOlCkWUly_rjuzkoXDEjw06sfLMTysN lykg- Received: from sonic.gate.mail.ne1.yahoo.com by sonic312.consmr.mail.gq1.yahoo.com with HTTP; Thu, 29 Aug 2019 23:30:17 +0000 Received: by smtp402.mail.gq1.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID f8639e220c8a96cf24b2b0474e56d17f; Thu, 29 Aug 2019 23:30:16 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, jmorris@namei.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org Cc: casey@schaufler-ca.com, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, paul@paul-moore.com, sds@tycho.nsa.gov Subject: [PATCH v8 22/28] SELinux: Verify LSM display sanity in binder Date: Thu, 29 Aug 2019 16:29:29 -0700 Message-Id: <20190829232935.7099-23-casey@schaufler-ca.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190829232935.7099-1-casey@schaufler-ca.com> References: <20190829232935.7099-1-casey@schaufler-ca.com> MIME-Version: 1.0 Sender: selinux-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: selinux@vger.kernel.org Verify that the tasks on the ends of a binder transaction use LSM display values that don't cause SELinux contexts to be interpreted by another LSM or another LSM's context to be interpreted by SELinux. No judgement is made in cases that where SELinux contexts are not used in the binder transaction. Signed-off-by: Casey Schaufler --- include/linux/security.h | 1 + security/selinux/hooks.c | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/include/linux/security.h b/include/linux/security.h index c16aea55be97..7fcc94ec8e04 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -125,6 +125,7 @@ struct lsmblob { u32 secid[LSMBLOB_ENTRIES]; }; +#define LSMBLOB_FIRST 0 /* First valid LSM slot number */ #define LSMBLOB_INVALID -1 /* Not a valid LSM slot number */ #define LSMBLOB_NEEDED -2 /* Slot requested on initialization */ #define LSMBLOB_NOT_NEEDED -3 /* Slot not requested */ diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 352be16a887d..2844f2ab7706 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -2009,6 +2009,28 @@ static inline u32 open_file_to_av(struct file *file) return av; } +/* + * Verify that if the "display" LSM is SELinux for either task + * that it is for both tasks. + */ +static inline bool compatible_task_displays(struct task_struct *here, + struct task_struct *there) +{ + int h = lsm_task_display(here); + int t = lsm_task_display(there); + + if (h == t) + return true; + + /* unspecified is only ok if SELinux isn't going to be involved */ + if (selinux_lsmid.slot == LSMBLOB_FIRST) + return ((h == LSMBLOB_FIRST && t == LSMBLOB_INVALID) || + (t == LSMBLOB_FIRST && h == LSMBLOB_INVALID)); + + /* it's ok only if neither display is SELinux */ + return (h != selinux_lsmid.slot && t != selinux_lsmid.slot); +} + /* Hook functions begin here. */ static int selinux_binder_set_context_mgr(struct task_struct *mgr) @@ -2016,6 +2038,9 @@ static int selinux_binder_set_context_mgr(struct task_struct *mgr) u32 mysid = current_sid(); u32 mgrsid = task_sid(mgr); + if (!compatible_task_displays(current, mgr)) + return -EINVAL; + return avc_has_perm(&selinux_state, mysid, mgrsid, SECCLASS_BINDER, BINDER__SET_CONTEXT_MGR, NULL); @@ -2029,6 +2054,9 @@ static int selinux_binder_transaction(struct task_struct *from, u32 tosid = task_sid(to); int rc; + if (!compatible_task_displays(from, to)) + return -EINVAL; + if (mysid != fromsid) { rc = avc_has_perm(&selinux_state, mysid, fromsid, SECCLASS_BINDER, @@ -2048,6 +2076,9 @@ static int selinux_binder_transfer_binder(struct task_struct *from, u32 fromsid = task_sid(from); u32 tosid = task_sid(to); + if (!compatible_task_displays(from, to)) + return -EINVAL; + return avc_has_perm(&selinux_state, fromsid, tosid, SECCLASS_BINDER, BINDER__TRANSFER, NULL); @@ -2064,6 +2095,9 @@ static int selinux_binder_transfer_file(struct task_struct *from, struct common_audit_data ad; int rc; + if (!compatible_task_displays(from, to)) + return -EINVAL; + ad.type = LSM_AUDIT_DATA_PATH; ad.u.path = file->f_path; From patchwork Thu Aug 29 23:29:30 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 11122675 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id BE05A14DE for ; Thu, 29 Aug 2019 23:30:23 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 8861C21874 for ; Thu, 29 Aug 2019 23:30:23 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="WN1WzKwy" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727122AbfH2XaX (ORCPT ); Thu, 29 Aug 2019 19:30:23 -0400 Received: from sonic310-28.consmr.mail.gq1.yahoo.com ([98.137.69.154]:39258 "EHLO sonic310-28.consmr.mail.gq1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728294AbfH2XaW (ORCPT ); Thu, 29 Aug 2019 19:30:22 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1567121418; bh=HVCMtag1ut+efbnuAfO1rwRUtys2BapnlHDQkcdMXdQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=WN1WzKwyoZQCKSxvrSOrh3/tB8R41UGI+Za9LTQA+fRYXfLLZnMo9kQOpq1um1cgaaDlNRYbUIcGqmxp4RMxPhrrhX943GjZoT7kDK1nGCX3yWHiKSIQpOnciAeNvDDRIzJtJUZ1BQC/2yXinEUe37kxe1eDB4Jnueo1AfCdE8Tc0qExBnqi3Jv661CLYz4BeNdsqIA4eZGxdCGYZIda75wwXcxnefhcIMUhGZU05j5zub7Eci2q2QdJQ650hnBVLjVKrIfzAToG5OF6hsLs41rNVirkJGTzFWagzx6j3GypBd0TRvJWcfsLvAskq/eUf+g/Sjrll9yQr5UJZ7j1ug== X-YMail-OSG: K8kxUn0VM1kknFvrlBNC7TuLN.axf7ybvFLQkZW6l0EiuaduTsLGJHCoSg1KxFv aNE20gr1yL2DS4sB0NXxRuOZ.fFuDaAKtUlRJBaUVLm5yASxWF7UC2KxnDPsfArPzaGNeoznA7AJ hIi5UXm7lAnjKXEA6.0eI1yzga4y2RaqM.ybHHla_GXNoGHqMh1GHxVeyrIWswD7GwXp29MmyIpH yhNn2LbyDJkvfsxQyMegMftHoqXAMW5cexEM8pwNDynv_HeRVNGBBH8MnShi1OyEqkGrgoQqEyfd Ee12y_gVLjl9W2tx_qyOFPjwV6Htg1y6kjIyANeA1L.2LL8kAbdbKNkYME3G1DrInOlqaouGi6Dw Cd_GhN3iBGFdsWYE2uM4KTcwnoYmCSaPmfs8Wlz9ktKiB8y.GKQUX0IDuXTkbFc3oXwANjezAtT1 RgudeJoYkhVehC92S.xxdOZGGPMV05JaBJUC4i.iBB9y7.OfhcJAkQOzcPpVT_ROZgadSs4tpDJ1 g_XtKMtRynuVPyF3oSTDGddSxTufV11D0htK_rcZ4SBqO3B5DuGQoE1NEwRm.34wzuSvgn2COejS rh5cKYu2K41RjecTpiwfO0MNXqwcOkZV.bviSkEyKVn4dLs.m4VsDjPLt22ClTq3TR7BfOiNMshs 28oRsZ9ImFi6yC2A7hrvd5MseI0qG6Qo7v.TThp4R_aBjBfZiV6HfoWWQ3jZn5k8TtAoawx98l3E OhNtYIKHqz4j89CIQXHT1yHD.fnwaSBJGjZInwVvEBONWCwZLSQxUTPv.u5QxLiURw7M.ugSsHQb s0y2em87PTLMKnc.ecHkI2w4kdkgbizkLhGokYf6g8.V10QH8nMmADeZfXYDX0LdqNxuKf2nqIUq TFiaRwOFOzP3appmOIR1Jjwsi1n7hwT81z.TZVQ6Q4hlRKOFjMpnqLjA9.0BWpk2LARVJO3mT8rc kRmh0TBWkqQAqKocP_B0jRvKsaVqU6T838CO4QywHvlSRpPSKajTaoHvhxQjtnzHAC5eh2NoZxho QYrPp8MnulEXfyAAGnp1qiUPzdmVUZcj2QRRpKOtpkYSAEsvjcKjaKIRx4wlTHOYWYB6yLybxglA 85heWpWGCNDKQEYugxVIAlplUq.4DgyXk1yOJ84Nz5Dq6uRnmMVuQRbr3EU3IYFynck8.6rLHoYh mzFM8l_UFjOg_91SyMIh0ayB.oE3VscZVWk_aQVKI7m7zxJdflia0YygOfhoyRHDeXUOa9Ph92Rb ijT01b4VgYYzD6KOKpuXFDYXIITjJizGNTwd4t7_.7QlTjHj4rgjWng_kQqiyvCgSh43Y9OYJOqW k.Q-- Received: from sonic.gate.mail.ne1.yahoo.com by sonic310.consmr.mail.gq1.yahoo.com with HTTP; Thu, 29 Aug 2019 23:30:18 +0000 Received: by smtp402.mail.gq1.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID f8639e220c8a96cf24b2b0474e56d17f; Thu, 29 Aug 2019 23:30:17 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, jmorris@namei.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org Cc: casey@schaufler-ca.com, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, paul@paul-moore.com, sds@tycho.nsa.gov Subject: [PATCH v8 23/28] Audit: Add subj_LSM fields when necessary Date: Thu, 29 Aug 2019 16:29:30 -0700 Message-Id: <20190829232935.7099-24-casey@schaufler-ca.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190829232935.7099-1-casey@schaufler-ca.com> References: <20190829232935.7099-1-casey@schaufler-ca.com> MIME-Version: 1.0 Sender: selinux-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: selinux@vger.kernel.org Add record entries to identify subject data for all of the security modules when there is more than one. Signed-off-by: Casey Schaufler --- drivers/android/binder.c | 2 +- include/linux/audit.h | 1 + include/linux/security.h | 9 ++++- include/net/scm.h | 3 +- kernel/audit.c | 40 ++++++++++++++++++- kernel/audit_fsnotify.c | 1 + kernel/auditfilter.c | 1 + kernel/auditsc.c | 10 +++-- net/ipv4/ip_sockglue.c | 2 +- net/netfilter/nf_conntrack_netlink.c | 4 +- net/netfilter/nf_conntrack_standalone.c | 2 +- net/netfilter/nfnetlink_queue.c | 2 +- net/netlabel/netlabel_unlabeled.c | 11 ++++-- net/netlabel/netlabel_user.c | 2 +- net/xfrm/xfrm_policy.c | 2 + net/xfrm/xfrm_state.c | 2 + security/integrity/ima/ima_api.c | 1 + security/integrity/integrity_audit.c | 1 + security/security.c | 51 +++++++++++++++++++++++-- 19 files changed, 124 insertions(+), 23 deletions(-) diff --git a/drivers/android/binder.c b/drivers/android/binder.c index 90bc4ce07cd2..cb44f59b9bbe 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -3121,7 +3121,7 @@ static void binder_transaction(struct binder_proc *proc, struct lsmblob blob; security_task_getsecid(proc->tsk, &blob); - ret = security_secid_to_secctx(&blob, &lsmctx); + ret = security_secid_to_secctx(&blob, &lsmctx, LSMBLOB_DISPLAY); if (ret) { return_error = BR_FAILED_REPLY; return_error_param = ret; diff --git a/include/linux/audit.h b/include/linux/audit.h index 1e69d9fe16da..306b404d419c 100644 --- a/include/linux/audit.h +++ b/include/linux/audit.h @@ -152,6 +152,7 @@ extern void audit_log_link_denied(const char *operation); extern void audit_log_lost(const char *message); extern int audit_log_task_context(struct audit_buffer *ab); +extern void audit_log_task_lsms(struct audit_buffer *ab); extern void audit_log_task_info(struct audit_buffer *ab); extern int audit_update_lsm_rules(void); diff --git a/include/linux/security.h b/include/linux/security.h index 7fcc94ec8e04..bdef0edd14c5 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -129,6 +129,8 @@ struct lsmblob { #define LSMBLOB_INVALID -1 /* Not a valid LSM slot number */ #define LSMBLOB_NEEDED -2 /* Slot requested on initialization */ #define LSMBLOB_NOT_NEEDED -3 /* Slot not requested */ +#define LSMBLOB_DISPLAY -4 /* Use the "display" slot */ +#define LSMBLOB_FIRST -5 /* Use the default "display" slot */ /** * lsmblob_init - initialize an lsmblob structure. @@ -178,6 +180,8 @@ static inline bool lsmblob_equal(struct lsmblob *bloba, struct lsmblob *blobb) return true; } +const char *security_lsm_slot_name(int slot); + /* These functions are in security/commoncap.c */ extern int cap_capable(const struct cred *cred, struct user_namespace *ns, int cap, unsigned int opts); @@ -482,7 +486,8 @@ int security_setprocattr(const char *lsm, const char *name, void *value, size_t size); int security_netlink_send(struct sock *sk, struct sk_buff *skb); int security_ismaclabel(const char *name); -int security_secid_to_secctx(struct lsmblob *blob, struct lsmcontext *cp); +int security_secid_to_secctx(struct lsmblob *blob, struct lsmcontext *cp, + int display); int security_secctx_to_secid(const char *secdata, u32 seclen, struct lsmblob *blob); void security_release_secctx(struct lsmcontext *cp); @@ -1263,7 +1268,7 @@ static inline int security_ismaclabel(const char *name) } static inline int security_secid_to_secctx(struct lsmblob *blob, - struct lsmcontext *cp) + struct lsmcontext *cp, int display) { return -EOPNOTSUPP; } diff --git a/include/net/scm.h b/include/net/scm.h index 4a6ad8caf423..8b5a4737e1b8 100644 --- a/include/net/scm.h +++ b/include/net/scm.h @@ -96,7 +96,8 @@ static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct sc int err; if (test_bit(SOCK_PASSSEC, &sock->flags)) { - err = security_secid_to_secctx(&scm->lsmblob, &context); + err = security_secid_to_secctx(&scm->lsmblob, &context, + LSMBLOB_DISPLAY); if (!err) { put_cmsg(msg, SOL_SOCKET, SCM_SECURITY, diff --git a/kernel/audit.c b/kernel/audit.c index e1dfd9c6df36..45ea36f1f1c5 100644 --- a/kernel/audit.c +++ b/kernel/audit.c @@ -405,6 +405,7 @@ static int audit_log_config_change(char *function_name, u32 new, u32 old, if (rc) allow_changes = 0; /* Something weird, deny request */ audit_log_format(ab, " res=%d", allow_changes); + audit_log_task_lsms(ab); audit_log_end(ab); return rc; } @@ -1110,6 +1111,7 @@ static void audit_log_feature_change(int which, u32 old_feature, u32 new_feature audit_log_format(ab, " feature=%s old=%u new=%u old_lock=%u new_lock=%u res=%d", audit_feature_names[which], !!old_feature, !!new_feature, !!old_lock, !!new_lock, res); + audit_log_task_lsms(ab); audit_log_end(ab); } @@ -1360,6 +1362,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) size--; audit_log_n_untrustedstring(ab, data, size); } + audit_log_task_lsms(ab); audit_log_end(ab); } break; @@ -1374,6 +1377,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) msg_type == AUDIT_ADD_RULE ? "add_rule" : "remove_rule", audit_enabled); + audit_log_task_lsms(ab); audit_log_end(ab); return -EPERM; } @@ -1387,6 +1391,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) audit_log_common_recv_msg(audit_context(), &ab, AUDIT_CONFIG_CHANGE); audit_log_format(ab, " op=trim res=1"); + audit_log_task_lsms(ab); audit_log_end(ab); break; case AUDIT_MAKE_EQUIV: { @@ -1422,6 +1427,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) audit_log_format(ab, " new="); audit_log_untrustedstring(ab, new); audit_log_format(ab, " res=%d", !err); + audit_log_task_lsms(ab); audit_log_end(ab); kfree(old); kfree(new); @@ -1431,7 +1437,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) len = 0; if (lsmblob_is_set(&audit_sig_lsm)) { err = security_secid_to_secctx(&audit_sig_lsm, - &context); + &context, LSMBLOB_FIRST); if (err) return err; } @@ -1490,6 +1496,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) " old-log_passwd=%d new-log_passwd=%d res=%d", old.enabled, s.enabled, old.log_passwd, s.log_passwd, !err); + audit_log_task_lsms(ab); audit_log_end(ab); break; } @@ -2068,6 +2075,33 @@ void audit_log_key(struct audit_buffer *ab, char *key) audit_log_format(ab, "(null)"); } +void audit_log_task_lsms(struct audit_buffer *ab) +{ + int i; + const char *lsm; + struct lsmblob blob; + struct lsmcontext context; + + /* + * Don't do anything unless there is more than one LSM + * with a security context to report. + */ + if (security_lsm_slot_name(1) == NULL) + return; + + security_task_getsecid(current, &blob); + + for (i = 0; i < LSMBLOB_ENTRIES; i++) { + lsm = security_lsm_slot_name(i); + if (lsm == NULL) + break; + if (security_secid_to_secctx(&blob, &context, i)) + continue; + audit_log_format(ab, " subj_%s=%s", lsm, context.context); + security_release_secctx(&context); + } +} + int audit_log_task_context(struct audit_buffer *ab) { int error; @@ -2078,7 +2112,7 @@ int audit_log_task_context(struct audit_buffer *ab) if (!lsmblob_is_set(&blob)) return 0; - error = security_secid_to_secctx(&blob, &context); + error = security_secid_to_secctx(&blob, &context, LSMBLOB_FIRST); if (error) { if (error != -EINVAL) goto error_path; @@ -2185,6 +2219,7 @@ void audit_log_link_denied(const char *operation) audit_log_format(ab, "op=%s", operation); audit_log_task_info(ab); audit_log_format(ab, " res=0"); + audit_log_task_lsms(ab); audit_log_end(ab); } @@ -2235,6 +2270,7 @@ static void audit_log_set_loginuid(kuid_t koldloginuid, kuid_t kloginuid, oldloginuid, loginuid, tty ? tty_name(tty) : "(none)", oldsessionid, sessionid, !rc); audit_put_tty(tty); + audit_log_task_lsms(ab); audit_log_end(ab); } diff --git a/kernel/audit_fsnotify.c b/kernel/audit_fsnotify.c index 37ae95cfb7f4..3a00583fa7fa 100644 --- a/kernel/audit_fsnotify.c +++ b/kernel/audit_fsnotify.c @@ -135,6 +135,7 @@ static void audit_mark_log_rule_change(struct audit_fsnotify_mark *audit_mark, c audit_log_untrustedstring(ab, audit_mark->path); audit_log_key(ab, rule->filterkey); audit_log_format(ab, " list=%d res=1", rule->listnr); + audit_log_task_lsms(ab); audit_log_end(ab); } diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c index 8f244c98bb57..508d784413da 100644 --- a/kernel/auditfilter.c +++ b/kernel/auditfilter.c @@ -1099,6 +1099,7 @@ static void audit_log_rule_change(char *action, struct audit_krule *rule, int re audit_log_format(ab, " op=%s", action); audit_log_key(ab, rule->filterkey); audit_log_format(ab, " list=%d res=%d", rule->listnr, res); + audit_log_task_lsms(ab); audit_log_end(ab); } diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 0478680cd0a8..46d7a58babd2 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -954,7 +954,7 @@ static int audit_log_pid_context(struct audit_context *context, pid_t pid, from_kuid(&init_user_ns, auid), from_kuid(&init_user_ns, uid), sessionid); if (lsmblob_is_set(blob)) { - if (security_secid_to_secctx(blob, &lsmctx)) { + if (security_secid_to_secctx(blob, &lsmctx, LSMBLOB_FIRST)) { audit_log_format(ab, " obj=(none)"); rc = 1; } else { @@ -1198,7 +1198,8 @@ static void show_special(struct audit_context *context, int *call_panic) struct lsmblob blob; lsmblob_init(&blob, osid); - if (security_secid_to_secctx(&blob, &lsmcxt)) { + if (security_secid_to_secctx(&blob, &lsmcxt, + LSMBLOB_FIRST)) { audit_log_format(ab, " osid=%u", osid); *call_panic = 1; } else { @@ -1351,7 +1352,7 @@ static void audit_log_name(struct audit_context *context, struct audit_names *n, struct lsmcontext lsmctx; lsmblob_init(&blob, n->osid); - if (security_secid_to_secctx(&blob, &lsmctx)) { + if (security_secid_to_secctx(&blob, &lsmctx, LSMBLOB_FIRST)) { audit_log_format(ab, " osid=%u", n->osid); if (call_panic) *call_panic = 2; @@ -1460,6 +1461,7 @@ static void audit_log_exit(void) audit_log_task_info(ab); audit_log_key(ab, context->filterkey); + audit_log_task_lsms(ab); audit_log_end(ab); for (aux = context->aux; aux; aux = aux->next) { @@ -2569,6 +2571,7 @@ void audit_core_dumps(long signr) return; audit_log_task(ab); audit_log_format(ab, " sig=%ld res=1", signr); + audit_log_task_lsms(ab); audit_log_end(ab); } @@ -2595,6 +2598,7 @@ void audit_seccomp(unsigned long syscall, long signr, int code) audit_log_format(ab, " sig=%ld arch=%x syscall=%ld compat=%d ip=0x%lx code=0x%x", signr, syscall_get_arch(), syscall, in_compat_syscall(), KSTK_EIP(current), code); + audit_log_task_lsms(ab); audit_log_end(ab); } diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c index 80ae0c5a1301..447fe60af0cd 100644 --- a/net/ipv4/ip_sockglue.c +++ b/net/ipv4/ip_sockglue.c @@ -138,7 +138,7 @@ static void ip_cmsg_recv_security(struct msghdr *msg, struct sk_buff *skb) if (err) return; - err = security_secid_to_secctx(&lb, &context); + err = security_secid_to_secctx(&lb, &context, LSMBLOB_DISPLAY); if (err) return; diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index 403307ff0fff..c870aebe99a3 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -333,7 +333,7 @@ static int ctnetlink_dump_secctx(struct sk_buff *skb, const struct nf_conn *ct) struct lsmcontext context; lsmblob_init(&blob, ct->secmark); - ret = security_secid_to_secctx(&blob, &context); + ret = security_secid_to_secctx(&blob, &context, LSMBLOB_DISPLAY); if (ret) return 0; @@ -621,7 +621,7 @@ static inline int ctnetlink_secctx_size(const struct nf_conn *ct) struct lsmcontext context; lsmblob_init(&blob, ct->secmark); - ret = security_secid_to_secctx(&blob, &context); + ret = security_secid_to_secctx(&blob, &context, LSMBLOB_DISPLAY); if (ret) return 0; diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c index fcb51ab2bb8b..60dd81eb6f89 100644 --- a/net/netfilter/nf_conntrack_standalone.c +++ b/net/netfilter/nf_conntrack_standalone.c @@ -177,7 +177,7 @@ static void ct_show_secctx(struct seq_file *s, const struct nf_conn *ct) struct lsmcontext context; lsmblob_init(&blob, ct->secmark); - ret = security_secid_to_secctx(&blob, &context); + ret = security_secid_to_secctx(&blob, &context, LSMBLOB_DISPLAY); if (ret) return; diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c index 58d5bd7a376e..ad4bb3f9c7dc 100644 --- a/net/netfilter/nfnetlink_queue.c +++ b/net/netfilter/nfnetlink_queue.c @@ -318,7 +318,7 @@ static u32 nfqnl_get_sk_secctx(struct sk_buff *skb, struct lsmcontext *context) if (skb->secmark) { /* Any LSM might be looking for the secmark */ lsmblob_init(&blob, skb->secmark); - security_secid_to_secctx(&blob, context); + security_secid_to_secctx(&blob, context, LSMBLOB_DISPLAY); } read_unlock_bh(&skb->sk->sk_callback_lock); diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c index 57ede7781c8f..cf34c163af20 100644 --- a/net/netlabel/netlabel_unlabeled.c +++ b/net/netlabel/netlabel_unlabeled.c @@ -450,7 +450,8 @@ int netlbl_unlhsh_add(struct net *net, unlhsh_add_return: rcu_read_unlock(); if (audit_buf != NULL) { - if (security_secid_to_secctx(lsmblob, &context) == 0) { + if (security_secid_to_secctx(lsmblob, &context, + LSMBLOB_FIRST) == 0) { audit_log_format(audit_buf, " sec_obj=%s", context.context); security_release_secctx(&context); @@ -505,7 +506,8 @@ static int netlbl_unlhsh_remove_addr4(struct net *net, if (dev != NULL) dev_put(dev); if (entry != NULL && - security_secid_to_secctx(&entry->lsmblob, &context) == 0) { + security_secid_to_secctx(&entry->lsmblob, &context, + LSMBLOB_FIRST) == 0) { audit_log_format(audit_buf, " sec_obj=%s", context.context); security_release_secctx(&context); @@ -565,7 +567,8 @@ static int netlbl_unlhsh_remove_addr6(struct net *net, if (dev != NULL) dev_put(dev); if (entry != NULL && - security_secid_to_secctx(&entry->lsmblob, &context) == 0) { + security_secid_to_secctx(&entry->lsmblob, &context, + LSMBLOB_FIRST) == 0) { audit_log_format(audit_buf, " sec_obj=%s", context.context); security_release_secctx(&context); @@ -1136,7 +1139,7 @@ static int netlbl_unlabel_staticlist_gen(u32 cmd, lsmb = (struct lsmblob *)&addr6->lsmblob; } - ret_val = security_secid_to_secctx(lsmb, &context); + ret_val = security_secid_to_secctx(lsmb, &context, LSMBLOB_FIRST); if (ret_val != 0) goto list_cb_failure; ret_val = nla_put(cb_arg->skb, diff --git a/net/netlabel/netlabel_user.c b/net/netlabel/netlabel_user.c index 2d1307f65250..193200955dbd 100644 --- a/net/netlabel/netlabel_user.c +++ b/net/netlabel/netlabel_user.c @@ -114,7 +114,7 @@ struct audit_buffer *netlbl_audit_start_common(int type, lsmblob_init(&blob, audit_info->secid); if (audit_info->secid != 0 && - security_secid_to_secctx(&blob, &context) == 0) { + security_secid_to_secctx(&blob, &context, LSMBLOB_FIRST) == 0) { audit_log_format(audit_buf, " subj=%s", context.context); security_release_secctx(&context); } diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 8d1a898d0ba5..5a67b2e5d941 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c @@ -3996,6 +3996,7 @@ void xfrm_audit_policy_add(struct xfrm_policy *xp, int result, bool task_valid) xfrm_audit_helper_usrinfo(task_valid, audit_buf); audit_log_format(audit_buf, " res=%u", result); xfrm_audit_common_policyinfo(xp, audit_buf); + audit_log_task_lsms(audit_buf); audit_log_end(audit_buf); } EXPORT_SYMBOL_GPL(xfrm_audit_policy_add); @@ -4011,6 +4012,7 @@ void xfrm_audit_policy_delete(struct xfrm_policy *xp, int result, xfrm_audit_helper_usrinfo(task_valid, audit_buf); audit_log_format(audit_buf, " res=%u", result); xfrm_audit_common_policyinfo(xp, audit_buf); + audit_log_task_lsms(audit_buf); audit_log_end(audit_buf); } EXPORT_SYMBOL_GPL(xfrm_audit_policy_delete); diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index 1bb971f46fc6..d6944123ca0e 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c @@ -2456,6 +2456,7 @@ void xfrm_audit_state_add(struct xfrm_state *x, int result, bool task_valid) xfrm_audit_helper_usrinfo(task_valid, audit_buf); xfrm_audit_helper_sainfo(x, audit_buf); audit_log_format(audit_buf, " res=%u", result); + audit_log_task_lsms(audit_buf); audit_log_end(audit_buf); } EXPORT_SYMBOL_GPL(xfrm_audit_state_add); @@ -2470,6 +2471,7 @@ void xfrm_audit_state_delete(struct xfrm_state *x, int result, bool task_valid) xfrm_audit_helper_usrinfo(task_valid, audit_buf); xfrm_audit_helper_sainfo(x, audit_buf); audit_log_format(audit_buf, " res=%u", result); + audit_log_task_lsms(audit_buf); audit_log_end(audit_buf); } EXPORT_SYMBOL_GPL(xfrm_audit_state_delete); diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c index 94b2a4840d81..1e96afcb2d8d 100644 --- a/security/integrity/ima/ima_api.c +++ b/security/integrity/ima/ima_api.c @@ -337,6 +337,7 @@ void ima_audit_measurement(struct integrity_iint_cache *iint, audit_log_format(ab, " hash=\"%s:%s\"", algo_name, hash); audit_log_task_info(ab); + audit_log_task_lsms(ab); audit_log_end(ab); iint->flags |= IMA_AUDITED; diff --git a/security/integrity/integrity_audit.c b/security/integrity/integrity_audit.c index 82c98f7d217e..aca1c6bdcccd 100644 --- a/security/integrity/integrity_audit.c +++ b/security/integrity/integrity_audit.c @@ -57,5 +57,6 @@ void integrity_audit_msg(int audit_msgno, struct inode *inode, audit_log_format(ab, " ino=%lu", inode->i_ino); } audit_log_format(ab, " res=%d", !result); + audit_log_task_lsms(ab); audit_log_end(ab); } diff --git a/security/security.c b/security/security.c index 20805ad99ccd..70aabbef51b2 100644 --- a/security/security.c +++ b/security/security.c @@ -434,7 +434,31 @@ static int lsm_append(const char *new, char **result) * Pointers to the LSM id structures for local use. */ static int lsm_slot __lsm_ro_after_init; -static struct lsm_id *lsm_slotlist[LSMBLOB_ENTRIES]; +static struct lsm_id *lsm_slotlist[LSMBLOB_ENTRIES] __lsm_ro_after_init; + +/** + * security_lsm_slot_name - Get the name of the security module in a slot + * @slot: index into the "display" slot list. + * + * Provide the name of the security module associated with + * a display slot. + * + * If @slot is LSMBLOB_INVALID return the value + * for slot 0 if it has been set, otherwise NULL. + * + * Returns a pointer to the name string or NULL. + */ +const char *security_lsm_slot_name(int slot) +{ + if (slot == LSMBLOB_INVALID) + slot = 0; + else if (slot >= LSMBLOB_ENTRIES || slot < 0) + return NULL; + + if (lsm_slotlist[slot] == NULL) + return NULL; + return lsm_slotlist[slot]->lsm; +} /** * security_add_hooks - Add a modules hooks to the hook lists. @@ -2121,13 +2145,32 @@ int security_ismaclabel(const char *name) } EXPORT_SYMBOL(security_ismaclabel); -int security_secid_to_secctx(struct lsmblob *blob, struct lsmcontext *cp) +int security_secid_to_secctx(struct lsmblob *blob, struct lsmcontext *cp, + int display) { struct security_hook_list *hp; - int display = lsm_task_display(current); memset(cp, 0, sizeof(*cp)); + /* + * display either is the slot number use for formatting + * or an instruction on which relative slot to use. + */ + if (display == LSMBLOB_DISPLAY) + display = lsm_task_display(current); + else if (display == LSMBLOB_FIRST) + display = LSMBLOB_INVALID; + else if (display < 0) { + WARN_ONCE(true, + "LSM: security_secid_to_secctx unknown display\n"); + display = LSMBLOB_INVALID; + } else if (display >= lsm_slot) { + WARN_ONCE(true, + "LSM: security_secid_to_secctx invalid display\n"); + display = LSMBLOB_INVALID; + } + + hlist_for_each_entry(hp, &security_hook_heads.secid_to_secctx, list) { if (WARN_ON(hp->lsmid->slot < 0 || hp->lsmid->slot >= lsm_slot)) continue; @@ -2138,7 +2181,7 @@ int security_secid_to_secctx(struct lsmblob *blob, struct lsmcontext *cp) &cp->context, &cp->len); } } - return 0; + return -EOPNOTSUPP; } EXPORT_SYMBOL(security_secid_to_secctx); From patchwork Thu Aug 29 23:29:31 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 11122669 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 6AB82112C for ; Thu, 29 Aug 2019 23:30:22 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 49BBD2189D for ; Thu, 29 Aug 2019 23:30:22 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="Odtz69Wd" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728262AbfH2XaV (ORCPT ); Thu, 29 Aug 2019 19:30:21 -0400 Received: from sonic302-28.consmr.mail.gq1.yahoo.com ([98.137.68.154]:39541 "EHLO sonic302-28.consmr.mail.gq1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728093AbfH2XaU (ORCPT ); Thu, 29 Aug 2019 19:30:20 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1567121419; bh=n9KYhenHMFy6/DvHoF7GAdIedxEuRn1itu30mtANhCU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=Odtz69WdwWJLGBHZyCaZ1Foo7iOFfwTA3mHk1ofhQI7HuUnpSx8kuKoqbDTYifQr5fA/lb1m6P+e8IR9AVBimo+kF2/rbiL+EkFmM0RKKBnXoYTzbnbxN546MADKY4Eyl/hBcIZYjlks4lj0zbwXspI+RYDxB3xISx0dlPng523R2DNXDFRBUl7NRxY30ab7W5dHB+1dTtsNSTxVtaIPg8XOpGRuzgF276VlDF1qn88lzbPMWf4KucVUret8p8dN4V48x6VG/qWtbRsYXDKVXW4QlyNKFCblkszxWJ9VXVXx+Dxu5UPl+XLLNhJHr+sMf+uMw4lb///PVMz/ss4JDg== X-YMail-OSG: Gitt1WkVM1nZyszDwbDW6YdZY_ktPUKQ35aD_lkizzvKKBgXXzAb5qpbNnaXAzC hURA.D1f4x6nDN3qEfL3vFUQP1Oxppv0oG_15IUP8kT6WI9SnYE3n39kHWT2VtzDdJvSKjJXrU90 rSLVN0fyzsQhxse29B_QfRtdPhZXo2V2Byr6g7tQGsaFbN5ZpWAtIu4Xq5lDwwHbHE9QcQAtvYIT wweSHPN6I9V_2nHX852FfEP3CMWzGB2WEgK6WeCBu018_iEgRWCjZLfyfrgiVQgfqZ_BxUYg1mqU WmreaYwcQoVmWvm_oztEN0uF2dEusKwfffeEfAhYcFAfgclfpynGGkxM8lLIThTIEtvyGtBGRJd0 CpDDJH7lzgDZAws2FrYNrG4AKJTbNDx9v.Du6REE_ISk1Oa6IxuZrFFZbJx9KAkGO0berOY9JF85 _JM1NKCbno.L2heTmDfevoZl4mIqlDr1s9qVH2WqzuaytmxCWghtMU.C5vwfeZ8n1S68zplT2lTz p2Zdw.aPD_coY6SVBFSB3j47cmcVolaTTzq8RrbI921qFDCDyZGC4Y8EO_Rc.70.35CvXEthb.y6 lFTjC6LzU4LPN0FP25dsJXlI3bpVJVzqxzpGmv.FeGX6q4osEkzlGjRFGQOrsOVxhoF7jb91YITn 0hrdZ6v8ASyOkUqM5T5_mhavsI.tNQceToAHxIk5RmPyG_vDoLUi3ubln6Gvxkl09iAoJuiLj2yt 3kLCkNf7PMV6XCokZWxiF4K1PqK47X4K_TveTue6_6koCh8b4CC6F5n6Id3DgONC8vahowf.dt2s 3YzVDDI5vIQgY_orKAv5doUEl9qXm8pt9BuzMnrm8bx7jPxvQd_8Ze9phVY6ZmS27qvVivo3A_lP s6tJ.HOxr7VY09pqsx9R93CBReSyZVff17ISGwEH.hAuZULZpwwasa4aQ98m_tgU8SrOpcQkBy8a 9rjd7p55EFIjh5yXbhHJykGs_UEkLk5pvhTMqi.g1mjZ7q__mQ4of7mEDXgQjZMk0bj9Uv6esL4U 1lIAhzyEi5668FQ81lVvP2mX3W.cgtA6lVhumnTB7M3.vMEyu4p00rhvR81Jy.DTl.mQhBD3LxKY tzQoR73SFdNzHpfh_HwAfyS7irKNjn_FlKgHKBZyr6NdjvqF7BN5niOHWLhOspJeiz5fWwZNRV2Y 3GybpKpT1LsZ6GL1GnoCRKQqmU9L3S.As8KO60VwuwTX.BJ_Z_QDsNouY.gHd68b.t1xGMYRuyEB NJ5VY30RT7s_sAOWiTsqPpP82MeyfP7VsneNEpJya0sOLdP9tBiBMez3cJ0XdM3P5J9JyUPUeRCm 7ts1LFPQ- Received: from sonic.gate.mail.ne1.yahoo.com by sonic302.consmr.mail.gq1.yahoo.com with HTTP; Thu, 29 Aug 2019 23:30:19 +0000 Received: by smtp402.mail.gq1.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID f8639e220c8a96cf24b2b0474e56d17f; Thu, 29 Aug 2019 23:30:18 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, jmorris@namei.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org Cc: casey@schaufler-ca.com, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, paul@paul-moore.com, sds@tycho.nsa.gov Subject: [PATCH v8 24/28] Audit: Include object data for all security modules Date: Thu, 29 Aug 2019 16:29:31 -0700 Message-Id: <20190829232935.7099-25-casey@schaufler-ca.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190829232935.7099-1-casey@schaufler-ca.com> References: <20190829232935.7099-1-casey@schaufler-ca.com> MIME-Version: 1.0 Sender: selinux-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: selinux@vger.kernel.org When there is more than one context displaying security module extend what goes into the audit record by supplimenting the "obj=" with an "obj_=" for each such security module. Signed-off-by: Casey Schaufler --- kernel/audit.h | 4 +- kernel/auditsc.c | 110 ++++++++++++++++++++++++----------------------- 2 files changed, 58 insertions(+), 56 deletions(-) diff --git a/kernel/audit.h b/kernel/audit.h index 29e29c6f4afb..af9a7d1fc069 100644 --- a/kernel/audit.h +++ b/kernel/audit.h @@ -91,7 +91,7 @@ struct audit_names { kuid_t uid; kgid_t gid; dev_t rdev; - u32 osid; + struct lsmblob oblob; struct audit_cap_data fcap; unsigned int fcap_ver; unsigned char type; /* record type */ @@ -165,7 +165,7 @@ struct audit_context { kuid_t uid; kgid_t gid; umode_t mode; - u32 osid; + struct lsmblob oblob; int has_perm; uid_t perm_uid; gid_t perm_gid; diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 46d7a58babd2..04367c3593e4 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -646,17 +646,15 @@ static int audit_filter_rules(struct task_struct *tsk, if (f->lsm_rule) { /* Find files that match */ if (name) { - lsmblob_init(&blob, name->osid); result = security_audit_rule_match( - &blob, + &name->oblob, f->type, f->op, f->lsm_rule); } else if (ctx) { list_for_each_entry(n, &ctx->names_list, list) { - lsmblob_init(&blob, n->osid); if (security_audit_rule_match( - &blob, + &n->oblob, f->type, f->op, f->lsm_rule)) { @@ -668,8 +666,7 @@ static int audit_filter_rules(struct task_struct *tsk, /* Find ipc objects that match */ if (!ctx || ctx->type != AUDIT_IPC) break; - lsmblob_init(&blob, ctx->ipc.osid); - if (security_audit_rule_match(&blob, + if (security_audit_rule_match(&ctx->ipc.oblob, f->type, f->op, f->lsm_rule)) ++result; @@ -937,13 +934,57 @@ static inline void audit_free_context(struct audit_context *context) kfree(context); } +static int audit_log_object_context(struct audit_buffer *ab, + struct lsmblob *blob) +{ + struct lsmcontext context; + const char *lsm; + int i; + + /* + * None of the installed modules have object labels. + */ + if (security_lsm_slot_name(0) == NULL) + return 0; + + if (blob->secid[0] != 0) { + if (security_secid_to_secctx(blob, &context, 0)) { + audit_log_format(ab, " obj=?"); + return 1; + } + audit_log_format(ab, " obj=%s", context.context); + security_release_secctx(&context); + } + + /* + * Don't do anything more unless there is more than one LSM + * with a security context to report. + */ + if (security_lsm_slot_name(1) == NULL) + return 0; + + for (i = 0; i < LSMBLOB_ENTRIES; i++) { + lsm = security_lsm_slot_name(i); + if (lsm == NULL) + break; + if (blob->secid[i] == 0) + continue; + if (security_secid_to_secctx(blob, &context, i)) { + audit_log_format(ab, " obj_%s=?", lsm); + continue; + } + audit_log_format(ab, " obj_%s=%s", lsm, context.context); + security_release_secctx(&context); + } + return 0; +} + static int audit_log_pid_context(struct audit_context *context, pid_t pid, kuid_t auid, kuid_t uid, unsigned int sessionid, struct lsmblob *blob, char *comm) { struct audit_buffer *ab; - struct lsmcontext lsmctx; int rc = 0; ab = audit_log_start(context, GFP_KERNEL, AUDIT_OBJ_PID); @@ -953,15 +994,7 @@ static int audit_log_pid_context(struct audit_context *context, pid_t pid, audit_log_format(ab, "opid=%d oauid=%d ouid=%d oses=%d", pid, from_kuid(&init_user_ns, auid), from_kuid(&init_user_ns, uid), sessionid); - if (lsmblob_is_set(blob)) { - if (security_secid_to_secctx(blob, &lsmctx, LSMBLOB_FIRST)) { - audit_log_format(ab, " obj=(none)"); - rc = 1; - } else { - audit_log_format(ab, " obj=%s", lsmctx.context); - security_release_secctx(&lsmctx); - } - } + rc = audit_log_object_context(ab, blob); audit_log_format(ab, " ocomm="); audit_log_untrustedstring(ab, comm); audit_log_end(ab); @@ -1187,26 +1220,14 @@ static void show_special(struct audit_context *context, int *call_panic) context->socketcall.args[i]); break; } case AUDIT_IPC: { - u32 osid = context->ipc.osid; + struct lsmblob *oblob = & context->ipc.oblob; audit_log_format(ab, "ouid=%u ogid=%u mode=%#ho", from_kuid(&init_user_ns, context->ipc.uid), from_kgid(&init_user_ns, context->ipc.gid), context->ipc.mode); - if (osid) { - struct lsmcontext lsmcxt; - struct lsmblob blob; - - lsmblob_init(&blob, osid); - if (security_secid_to_secctx(&blob, &lsmcxt, - LSMBLOB_FIRST)) { - audit_log_format(ab, " osid=%u", osid); - *call_panic = 1; - } else { - audit_log_format(ab, " obj=%s", lsmcxt.context); - security_release_secctx(&lsmcxt); - } - } + if (audit_log_object_context(ab, oblob)) + *call_panic = 1; if (context->ipc.has_perm) { audit_log_end(ab); ab = audit_log_start(context, GFP_KERNEL, @@ -1347,20 +1368,8 @@ static void audit_log_name(struct audit_context *context, struct audit_names *n, from_kgid(&init_user_ns, n->gid), MAJOR(n->rdev), MINOR(n->rdev)); - if (n->osid != 0) { - struct lsmblob blob; - struct lsmcontext lsmctx; - - lsmblob_init(&blob, n->osid); - if (security_secid_to_secctx(&blob, &lsmctx, LSMBLOB_FIRST)) { - audit_log_format(ab, " osid=%u", n->osid); - if (call_panic) - *call_panic = 2; - } else { - audit_log_format(ab, " obj=%s", lsmctx.context); - security_release_secctx(&lsmctx); - } - } + if (audit_log_object_context(ab, &n->oblob) && call_panic) + *call_panic = 2; /* log the audit_names record type */ switch (n->type) { @@ -1908,17 +1917,13 @@ static inline int audit_copy_fcaps(struct audit_names *name, void audit_copy_inode(struct audit_names *name, const struct dentry *dentry, struct inode *inode, unsigned int flags) { - struct lsmblob blob; - name->ino = inode->i_ino; name->dev = inode->i_sb->s_dev; name->mode = inode->i_mode; name->uid = inode->i_uid; name->gid = inode->i_gid; name->rdev = inode->i_rdev; - security_inode_getsecid(inode, &blob); - /* scaffolding until osid is updated */ - name->osid = blob.secid[0]; + security_inode_getsecid(inode, &name->oblob); if (flags & AUDIT_INODE_NOEVAL) { name->fcap_ver = -1; return; @@ -2268,14 +2273,11 @@ void __audit_mq_getsetattr(mqd_t mqdes, struct mq_attr *mqstat) void __audit_ipc_obj(struct kern_ipc_perm *ipcp) { struct audit_context *context = audit_context(); - struct lsmblob blob; context->ipc.uid = ipcp->uid; context->ipc.gid = ipcp->gid; context->ipc.mode = ipcp->mode; context->ipc.has_perm = 0; - security_ipc_getsecid(ipcp, &blob); - /* scaffolding on the [0] - change "osid" to a lsmblob */ - context->ipc.osid = blob.secid[0]; + security_ipc_getsecid(ipcp, &context->ipc.oblob); context->type = AUDIT_IPC; } From patchwork Thu Aug 29 23:29:32 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 11122677 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 49CBB112C for ; Thu, 29 Aug 2019 23:30:24 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 2779721874 for ; Thu, 29 Aug 2019 23:30:24 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="fHVydRV2" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728294AbfH2XaX (ORCPT ); Thu, 29 Aug 2019 19:30:23 -0400 Received: from sonic307-16.consmr.mail.ne1.yahoo.com ([66.163.190.39]:40981 "EHLO sonic307-16.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728093AbfH2XaX (ORCPT ); Thu, 29 Aug 2019 19:30:23 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1567121422; bh=k9N3chrEZiO+tPYw01Y1AA3KVSgvFnK+7jxWKSFUapg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=fHVydRV2VNy+v91wJCvWJuLoXOsHWDEP7xbVgY1/ixWovAHlaSq72QERaa+gJKzRjAhIcCE7yzBfGGSiyG/8j4ua2KTYZFWHLZdhpArrhmv/2vWtVoam6bKs9HO3gYE9b/YUNd7Mqo8FCJrC3jGkYLn9BDOtS/HIRdSOub4R83Kp7zfdLsF+07lfaQt3f5wTW0P74FQ7MMcvpdORrZlB9ZOlLTlHSAXpuOBqvTxc6EUvm1DKsZXC/1qOKGeVIKHv6m6ocHe7A06tL5uuMxcfwxv8J9iSkzG2x/xicCFDtWWN/72Uc4vmOMKDHxTvfncD6cHRya6UXgao3Fs61IuGtg== X-YMail-OSG: .kH9KnYVM1kLaOSw89s.zr8K8GC9mJqjhBi_ckPK7oPcyFeO0oF94f9EoTNMFVZ 80KxYv4Fpgol4AIrowdnmz7TV_UWd0q9PHnPBRgx4DN79TudJb5FUc2wVv4UZO4tsnsJTRIwRdhg E37DTkvunuSDZhwInadEC6xFtGf1Yy1KSe7iRiPXQXNLBR4lqoqLgWPnL.Gy1S1YV6x2rJ4.d7go 3F0gLllFZx1jEzVKQKunPnh8bn870T2Aidlvanfk1zQrM86UjDOyRg5UGcnXhJ991uGKlW7_3DDx R10ymCURjsey3FoR0xgQ_LSAwXM56J6nhoVSr.f8479dwqHPrEi2PB4s8ySd0Roc4lMMAzlfk79c Q_phi5B3qr7LHYxcoD7zw.UrVFcpz2K3SkTfyEtlTrAM5VyplfrhUbXsa1E69dVuTENeg22GknRY aJ5GJF1c5AqmzzLNJX7WBt2SNW47bmf0GP6zyzfOOgy0AooVhqOOD.iYi1UMANlSFIZ7uYGEW7XJ s7HR8C1rOXfqERHZzr1Xxn8I2Xse.Pa_0tXKJw_46pw_7pr6WuxYdgFLGf3jQqv17K1Vi44YLLgh TTq2jPlRuOYK9gQ0_mfVPeOKCaU.MEejg2LMYBk8LCmOnJHVmdh44qUYST_lVzJ8T2tIJyVNDRjG Gud_E0TqXCYDGk2NISU9oxk4cDOR1KinAHXt8i7D9byL002DgdqeH7.KYx.cYBWD2lluQZhWbDuB 5moE4YsgC3l9815sf1.vvNyayV29E4wMcljV6UT8BBnLzoUdscbzU0hEHpsqx2d8DaCpOgRv3g6j 90KVPJesdlsPR6WDb1vs1gHehQZOcYG0NkvNA5MEZmC8SGrTsOvk6S4Ed5MuFU0YqGXL6YyqWjUl Hs9EhPEFEl5u3UORTR2VOdVHQMCrT9bwG6ZygIlC7pTIlyImenlbPlhL8CBmr2XNwVwKWJZwHGO6 PFVLJBySLIc6YMOVXBPWWcITCc6OD._k0knO2LJInjNOH6xoohAY3TcMcC2wmaQ_Rtk5xtg99ZMh 8HlqsW6TANdV1nRfCx8w4SRVOqKw9u7GhYxPbJbUJMYjd8em352p6GmiovXhLEjgZguxqQvrFoFr 364CRUFYlEvO6Tq_XqtKSjfrHtMRMpO7iOoPIospLQ5KL1PXA4vsgErgQl3eZe5Dpnr316ejq8qK A42vdidce_HoJ9vOS9gH2Gvn6SRmSn5JMYXOAVWREyfdaFM32htnaXT321_2LwESC90AzfTh6rlL RpATQ22ZfH3eMJGd8buK.vYjqVKlG77ClxvtzVP153UojoSdS8GYNP02QXY2d8XJm2QsVFqceW6Y fbMvHWHzUpCwUvnpq Received: from sonic.gate.mail.ne1.yahoo.com by sonic307.consmr.mail.ne1.yahoo.com with HTTP; Thu, 29 Aug 2019 23:30:22 +0000 Received: by smtp408.mail.ne1.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID d0dbf8f29a1f39b20bf1052e42e06980; Thu, 29 Aug 2019 23:30:21 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, jmorris@namei.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org Cc: casey@schaufler-ca.com, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, paul@paul-moore.com, sds@tycho.nsa.gov Subject: [PATCH v8 25/28] LSM: Provide an user space interface for the default display Date: Thu, 29 Aug 2019 16:29:32 -0700 Message-Id: <20190829232935.7099-26-casey@schaufler-ca.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190829232935.7099-1-casey@schaufler-ca.com> References: <20190829232935.7099-1-casey@schaufler-ca.com> MIME-Version: 1.0 Sender: selinux-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: selinux@vger.kernel.org Create /sys/kernel/security/lsm_display_default which contains the name of the security module used when no display value has been set. Signed-off-by: Casey Schaufler --- security/inode.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/security/inode.c b/security/inode.c index b7772a9b315e..538a4d6796da 100644 --- a/security/inode.c +++ b/security/inode.c @@ -321,6 +321,22 @@ static const struct file_operations lsm_ops = { .read = lsm_read, .llseek = generic_file_llseek, }; + +static struct dentry *lsm_display_default_dentry; +static ssize_t lsm_display_default_read(struct file *filp, char __user *buf, + size_t count, loff_t *ppos) +{ + const char *name = security_lsm_slot_name(0); + + if (name == NULL) + return 0; + return simple_read_from_buffer(buf, count, ppos, name, strlen(name)); +} + +static const struct file_operations lsm_display_default_ops = { + .read = lsm_display_default_read, + .llseek = generic_file_llseek, +}; #endif static int __init securityfs_init(void) @@ -337,8 +353,10 @@ static int __init securityfs_init(void) return retval; } #ifdef CONFIG_SECURITY - lsm_dentry = securityfs_create_file("lsm", 0444, NULL, NULL, - &lsm_ops); + lsm_dentry = securityfs_create_file("lsm", 0444, NULL, NULL, &lsm_ops); + lsm_display_default_dentry = securityfs_create_file( + "lsm_display_default", 0444, NULL, + NULL, &lsm_display_default_ops); #endif return 0; } From patchwork Thu Aug 29 23:29:33 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 11122689 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id EEB7A112C for ; Thu, 29 Aug 2019 23:30:27 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id B983421874 for ; Thu, 29 Aug 2019 23:30:27 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="UlzvytO0" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727789AbfH2Xa1 (ORCPT ); Thu, 29 Aug 2019 19:30:27 -0400 Received: from sonic303-28.consmr.mail.ne1.yahoo.com ([66.163.188.154]:43836 "EHLO sonic303-28.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728313AbfH2Xa0 (ORCPT ); Thu, 29 Aug 2019 19:30:26 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1567121424; bh=f/21AvUDniSTlL2Be6mMMGvejUMTnT/f1N21Ip5Fy4s=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=UlzvytO0lM6z9pOmEEzphK0fTL0zMyp14DuqpYAx+eE6/MVKTVE7KSsPypemORXyBPv2nK9IeXVIRrSOzz1Reu/xjGXdV5nzLwKt2KpAVPbTe78+YOg3G8nTCzEhOzZST9w8medTuOWLQDHzrnaY5u3xyxHxCRdfvuahlkdEbQi7zCV7a30rnvB/8kRF1fejjUfWHNFDBSu6g6PxLQA5PrnwRV1MK1XvRdxuOhisqqXDq+9uWnxl45UxP26THoSUnG01q1EAcyrc4B4ynsV8aJKMHEHS7iDzBEpFS2LI0GShGU/QcWwzjPnlQ7g2BJN/IpET8Zp4M+Y4oVRwTLSjEw== X-YMail-OSG: PxMKDF8VM1m_48Nqd0_v7tEAOFJC5.OyeiwDx6wMAfrFeu6zbB8zBDKvAATlFfy 4NHUvOQrpqV9jJse1D9mwY9kxZzf8Kx2MGLZCA5eyIH_r1f_t.oOFNp.Kyd2fMQO97cV_m9m2PDW HgIINtHsxLTqPn98OuKD3aFA3st5KXoVRon9PIiVMVdZrHzHSr90R9Wl4qWUmTxyd9I5tnjBJCbv H0lWGPttlyWhkkfkfDWJ82Ez26t_2VMYfcLNS41kZJVxONpE661UGirttZpk04oAJi4B0KoWMfbW lX27da1BblyIkrXMc2m_a9CUh7ZEP2FOVG__w07R09IvGbxdL.IKxzQ2suvFCFyAPVfpwGCbp688 Q09G0IDb_AAAGI1VkAu5ikHthHbl3Vpf3Kp0K64NRXHqNu_czs54bDYruZ.upJSJ.nlJWSRdLcre O4Maa99DrUazhPpDOpMw52xEMOG8WEujJNxcvcLaxskidBUha02vfl2IoIXTP.JuXeSrR44FHUvu hqxk38ByMyRffO_Ozi8gAgYE4Ie8_fnWdpWuykZc9k4NxXH4Wkf41_IU5A0xBUnMtoRU4TpDMgX5 zHfNfxy9v1_H8ny4wJe3zw_Sl10MgaRPM3AeHtvayr4drbV_f4aNQe2.LFStkOIPiSlaC4eZmTW3 v_8LLWkrvta4MJM1trMlTRanZ.3iz1sW.jOTkIGe1zGmA1M_zKKdoAZiE0248MoH84ZfxD5xKGCg BkMZN3R3jBGnmOc7asLpgnq7KJR5xUPr0tNs15bswk114SlQEifTbHLn6oeQ9U4_lWUbJAT6yGEN NpQ057Alu6Uja1ou727bI3PI14Oa9cbrd8uRZ07gj636z6lBBDAAxzXKxq8spamWj3.nxY1Sr1kD 9bVPZ2rdfFbVLO7ggSN41I4NfceoTDAdJUH3A.qitwfhCFbyuZQql7eTjv3KFFM_nWXGt5SmTyZV lW1nB6EfDOXsdlv7tw0pzJsRXbaZ32FaoZt2KXXdAoKqfiYHYxBEyLlvsuOYbSkEpSDZs6HEh.qO qs7FEZUo3sYP_ERdLa4FzJ8OiguawDKToSP.ka01BEwqRAf3rQ6g5JB0z0wRNH57Rr9olzZMFWxi g_G5pHkT6Dj6Ts_S0kQ7DZL1hNzSmPup5Kc3ZwOs1O2mIsjcTb2xbVB5IF3c8CM7P_vdoby07YEw xBznW6GgQXbzTh4wVL676HqOe2norWRT1S0pT3Vf.BOzWSwRbd3Pqkj2Ogxmw02pegyDNhkNiKHw lBT2NG0CDiB9Fr4uuHaoeR9Yk_0UvUbv8U0BINHdIpJWHs26DwhFT0E2VWu0vKYLWw.5YAx6GHjs VSyZ2f8pxHtbIx4s3BJs- Received: from sonic.gate.mail.ne1.yahoo.com by sonic303.consmr.mail.ne1.yahoo.com with HTTP; Thu, 29 Aug 2019 23:30:24 +0000 Received: by smtp408.mail.ne1.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID d0dbf8f29a1f39b20bf1052e42e06980; Thu, 29 Aug 2019 23:30:22 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, jmorris@namei.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org Cc: casey@schaufler-ca.com, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, paul@paul-moore.com, sds@tycho.nsa.gov Subject: [PATCH v8 26/28] NET: Add SO_PEERCONTEXT for multiple LSMs Date: Thu, 29 Aug 2019 16:29:33 -0700 Message-Id: <20190829232935.7099-27-casey@schaufler-ca.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190829232935.7099-1-casey@schaufler-ca.com> References: <20190829232935.7099-1-casey@schaufler-ca.com> MIME-Version: 1.0 Sender: selinux-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: selinux@vger.kernel.org The getsockopt SO_PEERSEC provides the LSM based security information for a single module, but for reasons of backward compatibility cannot include the information for multiple modules. A new option SO_PEERCONTEXT is added to report the security "context" of multiple modules using a "compound" format lsm1\0value\0lsm2\0value\0 This is expected to be used by system services, including dbus-daemon. The exact format of a compound context has been the subject of considerable debate. This format was suggested by Simon McVittie, a dbus maintainer with a significant stake in the format being uasable. Signed-off-by: Casey Schaufler --- arch/alpha/include/uapi/asm/socket.h | 1 + arch/mips/include/uapi/asm/socket.h | 1 + arch/parisc/include/uapi/asm/socket.h | 1 + arch/sparc/include/uapi/asm/socket.h | 1 + include/linux/lsm_hooks.h | 9 +- include/linux/security.h | 11 ++- include/uapi/asm-generic/socket.h | 1 + net/core/sock.c | 7 +- security/apparmor/lsm.c | 20 ++--- security/security.c | 116 +++++++++++++++++++++++--- security/selinux/hooks.c | 20 ++--- security/smack/smack_lsm.c | 31 +++---- 12 files changed, 156 insertions(+), 63 deletions(-) diff --git a/arch/alpha/include/uapi/asm/socket.h b/arch/alpha/include/uapi/asm/socket.h index 976e89b116e5..019e5fa8bcda 100644 --- a/arch/alpha/include/uapi/asm/socket.h +++ b/arch/alpha/include/uapi/asm/socket.h @@ -121,6 +121,7 @@ #define SO_RCVTIMEO_NEW 66 #define SO_SNDTIMEO_NEW 67 +#define SO_PEERCONTEXT 68 #if !defined(__KERNEL__) diff --git a/arch/mips/include/uapi/asm/socket.h b/arch/mips/include/uapi/asm/socket.h index d41765cfbc6e..df8d984d76ed 100644 --- a/arch/mips/include/uapi/asm/socket.h +++ b/arch/mips/include/uapi/asm/socket.h @@ -132,6 +132,7 @@ #define SO_RCVTIMEO_NEW 66 #define SO_SNDTIMEO_NEW 67 +#define SO_PEERCONTEXT 68 #if !defined(__KERNEL__) diff --git a/arch/parisc/include/uapi/asm/socket.h b/arch/parisc/include/uapi/asm/socket.h index 66c5dd245ac7..9ae358309f46 100644 --- a/arch/parisc/include/uapi/asm/socket.h +++ b/arch/parisc/include/uapi/asm/socket.h @@ -113,6 +113,7 @@ #define SO_RCVTIMEO_NEW 0x4040 #define SO_SNDTIMEO_NEW 0x4041 +#define SO_PEERCONTEXT 0x4042 #if !defined(__KERNEL__) diff --git a/arch/sparc/include/uapi/asm/socket.h b/arch/sparc/include/uapi/asm/socket.h index 9265a9eece15..e8a53ef65210 100644 --- a/arch/sparc/include/uapi/asm/socket.h +++ b/arch/sparc/include/uapi/asm/socket.h @@ -114,6 +114,7 @@ #define SO_RCVTIMEO_NEW 0x0044 #define SO_SNDTIMEO_NEW 0x0045 +#define SO_PEERCONTEXT 0x0046 #if !defined(__KERNEL__) diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h index 33e5ab4af9f8..b0f788bf82b6 100644 --- a/include/linux/lsm_hooks.h +++ b/include/linux/lsm_hooks.h @@ -864,8 +864,8 @@ * SO_GETPEERSEC. For tcp sockets this can be meaningful if the * socket is associated with an ipsec SA. * @sock is the local socket. - * @optval userspace memory where the security state is to be copied. - * @optlen userspace int where the module should copy the actual length + * @optval memory where the security state is to be copied. + * @optlen int where the module should copy the actual length * of the security state. * @len as input is the maximum length to copy to userspace provided * by the caller. @@ -1697,9 +1697,8 @@ union security_list_options { int (*socket_setsockopt)(struct socket *sock, int level, int optname); int (*socket_shutdown)(struct socket *sock, int how); int (*socket_sock_rcv_skb)(struct sock *sk, struct sk_buff *skb); - int (*socket_getpeersec_stream)(struct socket *sock, - char __user *optval, - int __user *optlen, unsigned len); + int (*socket_getpeersec_stream)(struct socket *sock, char **optval, + int *optlen, unsigned len); int (*socket_getpeersec_dgram)(struct socket *sock, struct sk_buff *skb, u32 *secid); int (*sk_alloc_security)(struct sock *sk, int family, gfp_t priority); diff --git a/include/linux/security.h b/include/linux/security.h index bdef0edd14c5..d134ccff46b4 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -130,7 +130,7 @@ struct lsmblob { #define LSMBLOB_NEEDED -2 /* Slot requested on initialization */ #define LSMBLOB_NOT_NEEDED -3 /* Slot not requested */ #define LSMBLOB_DISPLAY -4 /* Use the "display" slot */ -#define LSMBLOB_FIRST -5 /* Use the default "display" slot */ +#define LSMBLOB_COMPOUND -5 /* A compound "display" */ /** * lsmblob_init - initialize an lsmblob structure. @@ -1325,7 +1325,8 @@ int security_socket_setsockopt(struct socket *sock, int level, int optname); int security_socket_shutdown(struct socket *sock, int how); int security_sock_rcv_skb(struct sock *sk, struct sk_buff *skb); int security_socket_getpeersec_stream(struct socket *sock, char __user *optval, - int __user *optlen, unsigned len); + int __user *optlen, unsigned len, + int display); int security_socket_getpeersec_dgram(struct socket *sock, struct sk_buff *skb, struct lsmblob *blob); int security_sk_alloc(struct sock *sk, int family, gfp_t priority); @@ -1459,8 +1460,10 @@ static inline int security_sock_rcv_skb(struct sock *sk, return 0; } -static inline int security_socket_getpeersec_stream(struct socket *sock, char __user *optval, - int __user *optlen, unsigned len) +static inline int security_socket_getpeersec_stream(struct socket *sock, + char __user *optval, + int __user *optlen, + unsigned len, int display) { return -ENOPROTOOPT; } diff --git a/include/uapi/asm-generic/socket.h b/include/uapi/asm-generic/socket.h index 8c1391c89171..b38d080c2802 100644 --- a/include/uapi/asm-generic/socket.h +++ b/include/uapi/asm-generic/socket.h @@ -116,6 +116,7 @@ #define SO_RCVTIMEO_NEW 66 #define SO_SNDTIMEO_NEW 67 +#define SO_PEERCONTEXT 68 #if !defined(__KERNEL__) diff --git a/net/core/sock.c b/net/core/sock.c index 782343bb925b..b0955a34167c 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -1412,7 +1412,12 @@ int sock_getsockopt(struct socket *sock, int level, int optname, break; case SO_PEERSEC: - return security_socket_getpeersec_stream(sock, optval, optlen, len); + return security_socket_getpeersec_stream(sock, optval, optlen, + len, LSMBLOB_DISPLAY); + + case SO_PEERCONTEXT: + return security_socket_getpeersec_stream(sock, optval, optlen, + len, LSMBLOB_COMPOUND); case SO_MARK: v.val = sk->sk_mark; diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c index ec2e39aa9a84..5d25959610f9 100644 --- a/security/apparmor/lsm.c +++ b/security/apparmor/lsm.c @@ -1037,10 +1037,8 @@ static struct aa_label *sk_peer_label(struct sock *sk) * * Note: for tcp only valid if using ipsec or cipso on lan */ -static int apparmor_socket_getpeersec_stream(struct socket *sock, - char __user *optval, - int __user *optlen, - unsigned int len) +static int apparmor_socket_getpeersec_stream(struct socket *sock, char **optval, + int *optlen, unsigned int len) { char *name; int slen, error = 0; @@ -1060,17 +1058,11 @@ static int apparmor_socket_getpeersec_stream(struct socket *sock, if (slen < 0) { error = -ENOMEM; } else { - if (slen > len) { + if (slen > len) error = -ERANGE; - } else if (copy_to_user(optval, name, slen)) { - error = -EFAULT; - goto out; - } - if (put_user(slen, optlen)) - error = -EFAULT; -out: - kfree(name); - + else + *optval = name; + *optlen = slen; } done: diff --git a/security/security.c b/security/security.c index 70aabbef51b2..8cb91f33c166 100644 --- a/security/security.c +++ b/security/security.c @@ -743,6 +743,42 @@ static int lsm_superblock_alloc(struct super_block *sb) return 0; } +/** + * append_ctx - append a lsm/context pair to a compound context + * @ctx: the existing compound context + * @ctxlen: size of the old context, including terminating nul byte + * @lsm: new lsm name, nul terminated + * @new: new context, possibly nul terminated + * @newlen: maximum size of @new + * + * replace @ctx with a new compound context, appending @newlsm and @new + * to @ctx. On exit the new data replaces the old, which is freed. + * @ctxlen is set to the new size, which includes a trailing nul byte. + * + * Returns 0 on success, -ENOMEM if no memory is available. + */ +static int append_ctx(char **ctx, int *ctxlen, const char *lsm, char *new, + int newlen) +{ + char *final; + int llen; + + llen = strlen(lsm) + 1; + newlen = strnlen(new, newlen) + 1; + + final = kzalloc(*ctxlen + llen + newlen, GFP_KERNEL); + if (final == NULL) + return -ENOMEM; + if (*ctxlen) + memcpy(final, *ctx, *ctxlen); + memcpy(final + *ctxlen, lsm, llen); + memcpy(final + *ctxlen + llen, new, newlen); + kfree(*ctx); + *ctx = final; + *ctxlen = *ctxlen + llen + newlen; + return 0; +} + /* * Hook list operation macros. * @@ -2126,8 +2162,8 @@ int security_setprocattr(const char *lsm, const char *name, void *value, hlist_for_each_entry(hp, &security_hook_heads.setprocattr, list) { if (lsm != NULL && strcmp(lsm, hp->lsmid->lsm)) continue; - if (lsm == NULL && *display != LSMBLOB_INVALID && - *display != hp->lsmid->slot) + if (lsm == NULL && display != NULL && + *display != LSMBLOB_INVALID && *display != hp->lsmid->slot) continue; return hp->hook.setprocattr(name, value, size); } @@ -2208,6 +2244,15 @@ void security_release_secctx(struct lsmcontext *cp) struct security_hook_list *hp; bool found = false; + if (cp->slot == LSMBLOB_INVALID) + return; + + if (cp->slot == LSMBLOB_COMPOUND) { + kfree(cp->context); + found = true; + goto clear_out; + } + hlist_for_each_entry(hp, &security_hook_heads.release_secctx, list) if (cp->slot == hp->lsmid->slot) { hp->hook.release_secctx(cp->context, cp->len); @@ -2215,6 +2260,7 @@ void security_release_secctx(struct lsmcontext *cp) break; } +clear_out: memset(cp, 0, sizeof(*cp)); if (!found) @@ -2351,17 +2397,67 @@ int security_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) EXPORT_SYMBOL(security_sock_rcv_skb); int security_socket_getpeersec_stream(struct socket *sock, char __user *optval, - int __user *optlen, unsigned len) + int __user *optlen, unsigned len, + int display) { - int display = lsm_task_display(current); struct security_hook_list *hp; + char *final = NULL; + char *cp; + int rc = 0; + unsigned finallen = 0; + unsigned clen = 0; - hlist_for_each_entry(hp, &security_hook_heads.socket_getpeersec_stream, - list) - if (display == LSMBLOB_INVALID || display == hp->lsmid->slot) - return hp->hook.socket_getpeersec_stream(sock, optval, - optlen, len); - return -ENOPROTOOPT; + switch (display) { + case LSMBLOB_DISPLAY: + rc = -ENOPROTOOPT; + display = lsm_task_display(current); + hlist_for_each_entry(hp, + &security_hook_heads.socket_getpeersec_stream, + list) + if (display == LSMBLOB_INVALID || + display == hp->lsmid->slot) { + rc = hp->hook.socket_getpeersec_stream(sock, + &final, &finallen, len); + break; + } + break; + case LSMBLOB_COMPOUND: + /* + * A compound context, in the form [lsm\0value\0]... + */ + hlist_for_each_entry(hp, + &security_hook_heads.socket_getpeersec_stream, + list) { + rc = hp->hook.socket_getpeersec_stream(sock, &cp, &clen, + len); + if (rc == -EINVAL || rc == -ENOPROTOOPT) { + rc = 0; + continue; + } + if (rc) { + kfree(final); + return rc; + } + rc = append_ctx(&final, &finallen, hp->lsmid->lsm, + cp, clen); + } + if (final == NULL) + return -EINVAL; + break; + default: + return -EINVAL; + } + + if (finallen > len) + rc = -ERANGE; + else if (copy_to_user(optval, final, finallen)) + rc = -EFAULT; + + if (put_user(finallen, optlen)) + rc = -EFAULT; + + kfree(final); + return rc; } int security_socket_getpeersec_dgram(struct socket *sock, struct sk_buff *skb, diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 2844f2ab7706..c8d469cc1b27 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -4923,10 +4923,8 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) return err; } -static int selinux_socket_getpeersec_stream(struct socket *sock, - char __user *optval, - int __user *optlen, - unsigned int len) +static int selinux_socket_getpeersec_stream(struct socket *sock, char **optval, + int *optlen, unsigned int len) { int err = 0; char *scontext; @@ -4946,18 +4944,12 @@ static int selinux_socket_getpeersec_stream(struct socket *sock, if (err) return err; - if (scontext_len > len) { + if (scontext_len > len) err = -ERANGE; - goto out_len; - } - - if (copy_to_user(optval, scontext, scontext_len)) - err = -EFAULT; + else + *optval = scontext; -out_len: - if (put_user(scontext_len, optlen)) - err = -EFAULT; - kfree(scontext); + *optlen = scontext_len; return err; } diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index 7a30b8692b1e..40c75205a914 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -3919,28 +3919,29 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) * * returns zero on success, an error code otherwise */ -static int smack_socket_getpeersec_stream(struct socket *sock, - char __user *optval, - int __user *optlen, unsigned len) +static int smack_socket_getpeersec_stream(struct socket *sock, char **optval, + int *optlen, unsigned len) { - struct socket_smack *ssp; - char *rcp = ""; - int slen = 1; + struct socket_smack *ssp = smack_sock(sock->sk); + char *rcp; + int slen; int rc = 0; - ssp = smack_sock(sock->sk); - if (ssp->smk_packet != NULL) { - rcp = ssp->smk_packet->smk_known; - slen = strlen(rcp) + 1; + if (ssp->smk_packet == NULL) { + *optlen = 0; + return -EINVAL; } + rcp = ssp->smk_packet->smk_known; + slen = strlen(rcp) + 1; if (slen > len) rc = -ERANGE; - else if (copy_to_user(optval, rcp, slen) != 0) - rc = -EFAULT; - - if (put_user(slen, optlen) != 0) - rc = -EFAULT; + else { + *optval = kstrdup(rcp, GFP_KERNEL); + if (*optval == NULL) + rc = -ENOMEM; + } + *optlen = slen; return rc; } From patchwork Thu Aug 29 23:29:34 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 11122687 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 5DFED14E5 for ; Thu, 29 Aug 2019 23:30:27 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 3C9DA2189D for ; Thu, 29 Aug 2019 23:30:27 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="sFR9WGQg" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728299AbfH2Xa0 (ORCPT ); Thu, 29 Aug 2019 19:30:26 -0400 Received: from sonic303-28.consmr.mail.ne1.yahoo.com ([66.163.188.154]:44838 "EHLO sonic303-28.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728309AbfH2Xa0 (ORCPT ); Thu, 29 Aug 2019 19:30:26 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1567121424; bh=EnzNGHlcb8dD+COQswLoSdxn1ohm9DzwqGsef/TOs/k=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=sFR9WGQgCuaMkXt4aj3ocQjQJ/K8beVcMOJzQgTHlANYlw9TFWdy6RBjqGJuZlcXoEmgdwbX1JBfLi0zYHbsfZYbRp9tpgnRtxWj68oZp8P+NF1rz6/0kB1k70E641LBznfga8yiIhmrjtOqg6nQJ1rp5LSeDhIHWZ+Ku1qNjtFm0cs/FPbvd5q7FhwCIQ+u/Ber145epFkTUcwE/H4OCo8Y6SwIjTa5shVlw4wU2o4s2pPHv5j6Lykp/CLAzWdv6bgp+0n/Jh9Y1hZy/gwVV7ZgtQoig6QkoSuhlvmbZ40oE+KKNbNuhufTIEo8C/MU42G9SbPdkjdx2aY7aiDwiQ== X-YMail-OSG: zXyIcH4VM1mbyx2rvidqdSrgRkvB9xD4BQbrkhBmIkatyzyP7syxQvM7eIdQymR 0W1WppExH8Fi336sTAbN.0cEiiLTehqyOtC1xnz.mhYAXvJEnyHEzA5sPdKJq6pGYNijEh3hSv6R n699mvmnfeFlklE7gglgrvuLcsO9KCJaGziTbD_SZJQxg8XmpOwwWhGTYaOwYoKfRFpcbGNonXby dn3WvdVHitrm4p_PBLYw1_TxmfEvQyq4wc6v9uBf_0iKhWnTaunKfjId1VOSC8WQ.AT4p4ECBj9U HmYXi.uCMmMsiP8RJBDH2x.h4HOiKcLzSvdHL.h6qtcw1RaCrGEhT0RfNNPmZ6sFLTzrt7oVyDjD .so8XRyG9BXBmRuKsMz7ypP40xj5_0aIexjlH6N.BdtvkvWs07XcVnylkNtU9Au7AZlqnBwTydmn kJrNH0Ny9cZwvBmSrJHytOb0ok04dhSj65BnlHab5P4vvlMgbZIWCbL6Ki7nv8khItDVD5lY6NkC EO3Ci2RzHwTZ9AzqO.YV04hRzUVhfbE9SxOcWwk1EL0ClS4mAVtDkapruLgIBnQ67XhWkzjRKB0P A6kgIHKJGiGooZ7es3JcS.t0DgpJPz7fuH_4dQjldaJsgA6NYVGrremet1WqrsbrFvwQl1x1tlgv 2LN4TmoaTeUnl77aE5Zpi7Qo5xs_NQoN.TUGC4tj5E8rp4CiL74AhDBBY6rwyFKlQLRgpqjU61Ob YRvzxesHc2SjK5J_yQvFFHOLMKW3N953PMhdr4E1aYWvceJiVnw6Kg1TRxS2elRAOvYj9fljwR7j T660jMECjbdljqxdNlvm_CocQCCuOAY5LGGe1FqXAkm3agXtnnAsmRJjFiyJcDb9jsxbN7v8Slnd x7.5kgoUHQPyjmAhcAtJK0OUdJJitQ6tEclXauAPUIpAhS3hQWKdlQZw0v4h0XuPh8F_QJGo5Tgl 5Ro_UZbKEOmED5gaYdTu1mpJNdssS4GpIiGz53KqfJ0H9Q1HPJqLbsypmMmbnfe.uyaEehFwdVSY tj_xsGR01AVOzcnigDn6zI9Srztz6eyQiWQdGrMatep6vRdMjTFQRIpubDgr3.w9TUrl0Xjs._u8 7pWzcwaYiwUMwYBgm0YwVLQ7.SrkQwEtfw6R4.dCr03cnhH9dOV8NzGJ3i_pZyqTkrRvaClJmdZU KTVcqQRuGjWnyBkdFexJoEUP_lKDjBookYurkVVkPoj3HeOHj33VmZulAOOq_PuJSs3mftkJu0XP 8n9GlMdIDzB4d8iIOhTfUxXjFdcC0n6NdMl_XgMz96r63XMCmyBFJLpJXgQ6TAsVoBQDFohUyY7q IN8eWUjJFxYyjMIo- Received: from sonic.gate.mail.ne1.yahoo.com by sonic303.consmr.mail.ne1.yahoo.com with HTTP; Thu, 29 Aug 2019 23:30:24 +0000 Received: by smtp408.mail.ne1.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID d0dbf8f29a1f39b20bf1052e42e06980; Thu, 29 Aug 2019 23:30:23 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, jmorris@namei.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org Cc: casey@schaufler-ca.com, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, paul@paul-moore.com, sds@tycho.nsa.gov Subject: [PATCH v8 27/28] LSM: Add /proc attr entry for full LSM context Date: Thu, 29 Aug 2019 16:29:34 -0700 Message-Id: <20190829232935.7099-28-casey@schaufler-ca.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190829232935.7099-1-casey@schaufler-ca.com> References: <20190829232935.7099-1-casey@schaufler-ca.com> MIME-Version: 1.0 Sender: selinux-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: selinux@vger.kernel.org Add an entry /proc/.../attr/context which displays the full process security "context" in compound format:' lsm1\0value\0lsm2\0value\0... This entry is not writable. Signed-off-by: Casey Schaufler --- fs/proc/base.c | 1 + security/security.c | 27 +++++++++++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/fs/proc/base.c b/fs/proc/base.c index 7bf70e041315..79600df5f7a2 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -2619,6 +2619,7 @@ static const struct pid_entry attr_dir_stuff[] = { ATTR(NULL, "keycreate", 0666), ATTR(NULL, "sockcreate", 0666), ATTR(NULL, "display", 0666), + ATTR(NULL, "context", 0666), #ifdef CONFIG_SECURITY_SMACK DIR("smack", 0555, proc_smack_attr_dir_inode_ops, proc_smack_attr_dir_ops), diff --git a/security/security.c b/security/security.c index 8cb91f33c166..d151ac4a398b 100644 --- a/security/security.c +++ b/security/security.c @@ -2082,6 +2082,10 @@ int security_getprocattr(struct task_struct *p, const char *lsm, char *name, char **value) { struct security_hook_list *hp; + char *final = NULL; + char *cp; + int rc = 0; + int finallen = 0; int display = lsm_task_display(current); int slot = 0; @@ -2099,6 +2103,29 @@ int security_getprocattr(struct task_struct *p, const char *lsm, char *name, return -ENOMEM; } + if (!strcmp(name, "context")) { + hlist_for_each_entry(hp, &security_hook_heads.getprocattr, + list) { + rc = hp->hook.getprocattr(p, "current", &cp); + if (rc == -EINVAL || rc == -ENOPROTOOPT) + continue; + if (rc < 0) { + kfree(final); + return rc; + } + rc = append_ctx(&final, &finallen, hp->lsmid->lsm, + cp, rc); + if (rc < 0) { + kfree(final); + return rc; + } + } + if (final == NULL) + return -EINVAL; + *value = final; + return finallen; + } + hlist_for_each_entry(hp, &security_hook_heads.getprocattr, list) { if (lsm != NULL && strcmp(lsm, hp->lsmid->lsm)) continue; From patchwork Thu Aug 29 23:29:35 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 11122683 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 8291214E5 for ; Thu, 29 Aug 2019 23:30:26 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 60E282189D for ; Thu, 29 Aug 2019 23:30:26 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="sf8FaplB" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728317AbfH2Xa0 (ORCPT ); Thu, 29 Aug 2019 19:30:26 -0400 Received: from sonic303-28.consmr.mail.ne1.yahoo.com ([66.163.188.154]:39293 "EHLO sonic303-28.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728299AbfH2XaZ (ORCPT ); Thu, 29 Aug 2019 19:30:25 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1567121424; bh=bTpYSfOPPyQC93rL07mL99qbU5sEPagdbqHFlgN48s4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=sf8FaplBhhdBf6vSm5Xr17BLtcflyUsZ6fcvJoA46sg2FpsBSiUTYYHbVJ5o7x04YDYxL1iKutuvfzmL3y2eIJQzMIRQAtdm4g9vZmLdfA+ASMLsT2HxM8ZvkNqE73Gw7z9ajSEClRYnKrthhJi8pmqsg0Bd3SSWMG1e9FSx1wAhXDb5pKAhYtK9ZLptHkJ9I0li2sGsqAOzaF5l6BpkHggXKTs0/jwHzeS7Vph3N2cVXYgV1k4zntB1blkmHjtHJpQ0Sd0AkR0aNNZ2P9BVQOin1baKkakRL/YmZCUQvFoKsXaJum0YQVwZRoDnfB9CCOh4ubF/OCRMO3Q1TaGlow== X-YMail-OSG: G76YARAVM1nujaGxjU1QYhUmz4a2wGhNuid9b1IXb4ype2nnTG7mEyoYVSqZNBl cDf3P8LCE0eSUsawEs3NiTYzRwO07w1_bmpWfj7lMKWXM7xc50A5E7FUNXPjU0NmpnsRCvTz5tT1 3oodvAhKbz2uCC_qMlBEs.Qcoi5IVtfd9dNgY0WBV5NwcdQRKBLOLeUF_PBQ4qblK2hjTYAvHqJw aW2azpVybcMzCbIncyK5ojyeLPz0sEmWi1LdSNi4YjT9RYkgktSciNwbLIbf56wmFwPN6LKhpDas 4rM8_0KwsR2pw.9kwbpW2lVSwTa9.ho4Po43A22tZJtrTgfjNDGgfWKtKb6MecF49q1awif.hjQt AV5EXSMzo1sItZon3QfU8i1.tElTizkDYo9rXZwzcVbgkJ0fQnfNpKFswHvXsVhkuPQ86RZba5ja jOJ2w823e6wZHPNFMjHw5LZECdpclqNV6CFUB6YSy8lcBx5LcAZ_nAm9dgljW45N12JVjOr9bFdo JJpjRjhp.ufdYYbFtbZtwmwwxqyiM.7epWve_GdRAKElAKtPASCO32e.siYjsXVLaPPjKZGWfw0C 73dVHamUb7gWauuCgGn0ku.WJ_Fyq_y.H4h8r62mGGFBn5ukjEkb03eziiXwsVNgbfBHVAVSLTUc Iq9sJwCKzxbSUyFjNlKA7z4PPy7jpYA_8AF1McDh.8HlXAIIHwTgFLOoQ6As6wnXUlbIuiNSu.b. nUDvSuN361JBBKAt8kQFF5RcDbBfCgSvTVKQBEy8AM74gxzaS6Bi1ia5oo6lXj4oafV5AsnZuj2U RIrzGCG5Wi6u.WOsXK42NbOsBhg1e3PlCgMwYichFJg3pyFLBM9TTxmnf26_pK817vfEyectkf7H rwiaQplicU8WhubsOTqSoMJVvUKDY0sbUxqsRiYNAL9EYhTn5inYl4DSDRKNAdaVpOrVV1Jxis_n 7qzFOZTmqgw0rgZL5H0o.8mNlIy2jhAfdVN_uumGxWUJIZP_sbTOwLxbBP05Tnd1uP0IbT9FfWVy 7J5x3WAXLUJLJ0KQ_hlmCcsTvzGWF9kCSJu3.m8zUeZg.hB00VFKj5xmRxbnj8b7YwVKigl.DEBZ BA_9u0j.aI6gYpCbxnyEbdexZQJZXoORb_HHXxRAzMyeKtPenIpDhRr_dkNTFGIcWwUIWwMbK8iV QGSiMEmBNTsCe6pHddWMoz1lytqNeAtAqsFchJ68y6GZIDig6Ep07HKMjMWWE0UCCXKrcMcwBnFR ZY_ii1omXdOHP3c14Ixk7tY9Us4HlK5G_2eBQsrWG0llnfXxSuQsWleIeY6YvraD9lYWuR4UAaW1 CiYkVm1fLvgMJJla8TmAOJg-- Received: from sonic.gate.mail.ne1.yahoo.com by sonic303.consmr.mail.ne1.yahoo.com with HTTP; Thu, 29 Aug 2019 23:30:24 +0000 Received: by smtp408.mail.ne1.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID d0dbf8f29a1f39b20bf1052e42e06980; Thu, 29 Aug 2019 23:30:23 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, jmorris@namei.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org Cc: casey@schaufler-ca.com, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, paul@paul-moore.com, sds@tycho.nsa.gov Subject: [PATCH v8 28/28] AppArmor: Remove the exclusive flag Date: Thu, 29 Aug 2019 16:29:35 -0700 Message-Id: <20190829232935.7099-29-casey@schaufler-ca.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190829232935.7099-1-casey@schaufler-ca.com> References: <20190829232935.7099-1-casey@schaufler-ca.com> MIME-Version: 1.0 Sender: selinux-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: selinux@vger.kernel.org With the inclusion of the "display" process attribute mechanism AppArmor no longer needs to be treated as an "exclusive" security module. Remove the flag that indicates it is exclusive. Remove the stub getpeersec_dgram AppArmor hook as it has no effect in the single LSM case and interferes in the multiple LSM case. Reviewed-by: Kees Cook Reviewed-by: John Johansen Signed-off-by: Casey Schaufler --- security/apparmor/lsm.c | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c index 5d25959610f9..fb5d5af426c6 100644 --- a/security/apparmor/lsm.c +++ b/security/apparmor/lsm.c @@ -1071,22 +1071,6 @@ static int apparmor_socket_getpeersec_stream(struct socket *sock, char **optval, return error; } -/** - * apparmor_socket_getpeersec_dgram - get security label of packet - * @sock: the peer socket - * @skb: packet data - * @secid: pointer to where to put the secid of the packet - * - * Sets the netlabel socket state on sk from parent - */ -static int apparmor_socket_getpeersec_dgram(struct socket *sock, - struct sk_buff *skb, u32 *secid) - -{ - /* TODO: requires secid support */ - return -ENOPROTOOPT; -} - /** * apparmor_sock_graft - Initialize newly created socket * @sk: child sock @@ -1190,8 +1174,6 @@ static struct security_hook_list apparmor_hooks[] __lsm_ro_after_init = { #endif LSM_HOOK_INIT(socket_getpeersec_stream, apparmor_socket_getpeersec_stream), - LSM_HOOK_INIT(socket_getpeersec_dgram, - apparmor_socket_getpeersec_dgram), LSM_HOOK_INIT(sock_graft, apparmor_sock_graft), #ifdef CONFIG_NETWORK_SECMARK LSM_HOOK_INIT(inet_conn_request, apparmor_inet_conn_request), @@ -1702,7 +1684,7 @@ static int __init apparmor_init(void) DEFINE_LSM(apparmor) = { .name = "apparmor", - .flags = LSM_FLAG_LEGACY_MAJOR | LSM_FLAG_EXCLUSIVE, + .flags = LSM_FLAG_LEGACY_MAJOR, .enabled = &apparmor_enabled, .blobs = &apparmor_blob_sizes, .init = apparmor_init,