From patchwork Fri Apr 19 00:45:56 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 10908541 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 083EB1515 for ; Fri, 19 Apr 2019 00:49:03 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id ED4F228B9C for ; Fri, 19 Apr 2019 00:49:02 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E1BE728BAC; Fri, 19 Apr 2019 00:49:02 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7CCE428CA9 for ; Fri, 19 Apr 2019 00:49:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727039AbfDSAtC (ORCPT ); Thu, 18 Apr 2019 20:49:02 -0400 Received: from sonic310-23.consmr.mail.bf2.yahoo.com ([74.6.135.197]:40459 "EHLO sonic310-23.consmr.mail.bf2.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727030AbfDSAtB (ORCPT ); Thu, 18 Apr 2019 20:49:01 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1555634940; bh=48+5U+50jFm6f0Nxz7VZWq9WDAQQ3RN6UxLpN1fpkp4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=eZRDDxVdqNZulrvKaDrgCGwAsFxAHwO+CUQ1m2WG3L91pxh/jnsjzAc7Duas5SF0Z/LCH0/GB7xjywRXw9P/kNtREPwyEWlI4zeLr+kmZFrbU7EAWhn4z5DwQBMprSEj3+Bz8p+zet4H3ykGyjbKXl+2e4wXj6dZ+bYbyHPudyKyNR7idYd0H3lCgKoFZJ1/+pGcMlvYZNVD23kcH0hzxp7Nq8h/JmQ7naNPxyErfWUrXif8Tyn7AiaSDK9FNZW/SO7/Cz48r3/kWLXbzeNEUqaNjiwAd0d4jOAV9gS/5KxJGaqlISHycyJOk5o62AX7C7QpP6nD6R+ZYyIoJd1JhQ== X-YMail-OSG: XTNKt_cVM1nfmoc4nlQ9LkojrCTFRUWLXRQme9ry8pvUgEo4ff0Rn3IGW2JcO98 .c4Tubj518xQeoDyhBl0XQ1hq_2GRCK8zq2RXLQ9BMflMVBRK864ZRqiDijwBRmgK97oGO.1PBZU WBIjzz.W1XVyVz4NmRAj5OuKdz3OPvx6iYOqnIvH2Igo9iCssembyUcXpkRIGel5n.IZuzO4mJMi 8sovGU.1q_wtAwImVQPvQzytRVCZvI5103E4Mzo_pSB9r2X48ZIlDxFC39VYXCZ7aLzQgfeFdM1R EQBH7uuU5V00ZGdHSExyN9zn1LzaWU8lvDDKb.GzviwCC0P.lMorpeqI.ImEjy3yYFmLuEb4BwF1 82hahZ34xxh5LABTLVC_t41cF32wCD_WkvY3R6NsBQ4munuN_YbQt7MqMCJvnbDb_Gpjuiouyb.7 XWXgnj3I55SmSc0RfLcdv4WdsNlFab9RIWb2Y8AKrlm_5fZPQT1aZqI16r.2dhRVE50fLC2bwjIo bmfe.If0yKWQVqFP8YN5NMNJj3ya54iM1UmpvppjpwkVBtycIDtxM9_qBthUJXYSoSquaeCWA4cC QNaDFanvKi3IpmtsXZbejlc3yBTIdLyydbujd4XY.XXSycFoYl1ms5NSGQoNoDH7Kdadno4JeXIc e1dypFJNQVjw6i6GcWMX6Lu9NTkco7eIRQe.7Y4FrLiBH57a6Ctu6xR7HmYIaU2SHs3TqZIYvVTv 6tE1s17Jcjf2msKvCxAu16rB2Urs1BAr8jKEBBe6XZr_s8iy80twFxUZ1HPq4QCNPuNN0Nkj_fKE sqqifBqi3APWQ4DzBQk_fXF2cUE5HfPaCJfJ32rm61FNreN3PLIg_HyN2AFyK2dHr.o.zW5SmWew C.Rj6lXul0fojVxKThw0wDgTpVJwDNpZEwZFozpsc3aXSakgb12skOI48nPYMw0Fc9nFU.6sy.Wc LJfy8ptfDBYgPswkJOjIsrYoBDvonUFmxf2Se_eAaMTKU7G1Db3FVEY2QJnlp9EcLAKJwKNe1.BH qdyJi2dF9jNVs4Yrhir01N2tdbCvcBtlkBOTfjkHdgnGpD4cuWWv.Gh8Itcpv2DIecVOU1ylCOJT 5s2EbBDslVCX6PKOpGzC7UOf_bw2IoLjmlRzlDzocrz3t_9V78ww7o4pMZo39wspDNkvzMB4ik67 VPBSxR3ncc4rwnw-- Received: from sonic.gate.mail.ne1.yahoo.com by sonic310.consmr.mail.bf2.yahoo.com with HTTP; Fri, 19 Apr 2019 00:49:00 +0000 Received: from c-67-169-65-224.hsd1.ca.comcast.net (EHLO localhost.localdomain) ([67.169.65.224]) by smtp432.mail.bf1.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID 406f9efc49df2aab5b39f3872aa73829; Fri, 19 Apr 2019 00:48:57 +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 Subject: [PATCH 69/90] LSM: Use full security context in security_inode_setsecctx Date: Thu, 18 Apr 2019 17:45:56 -0700 Message-Id: <20190419004617.64627-70-casey@schaufler-ca.com> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20190419004617.64627-1-casey@schaufler-ca.com> References: <20190419004617.64627-1-casey@schaufler-ca.com> Sender: selinux-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: selinux@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The security hooks security_inode_setsecctx and security_inode_getsecctx need to maintain the context strings for any and all LSMs that provide contexts. This information is internal to the kernel and volitile. If only one LSM uses this information the raw form is used. Signed-off-by: Casey Schaufler --- security/security.c | 110 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 108 insertions(+), 2 deletions(-) diff --git a/security/security.c b/security/security.c index b8c90e7c4554..05a19b28e105 100644 --- a/security/security.c +++ b/security/security.c @@ -425,6 +425,9 @@ static int lsm_append(char *new, char **result) /* Base list of once-only hooks */ struct lsm_one_hooks lsm_base_one; +/* Count of inode_[gs]etsecctx hooks */ +static int lsm_inode_secctx_count; + /** * security_add_hooks - Add a modules hooks to the hook lists. * @hooks: the hooks to add @@ -442,6 +445,15 @@ void __init security_add_hooks(struct security_hook_list *hooks, int count, hooks[i].lsm = lsm; hlist_add_tail_rcu(&hooks[i].list, hooks[i].head); + /* + * Keep count of the internal security context using hooks. + * Assume that there is a 1:1 mapping from inode_getsecctx + * to inode_setsecctx in the security modules. + */ + if (hooks[i].head == &security_hook_heads.inode_getsecctx) { + lsm_inode_secctx_count++; + continue; + } /* * Check for the special hooks that are restricted to * a single module to create the base set. Use the hooks @@ -2150,15 +2162,109 @@ int security_inode_notifysecctx(struct inode *inode, struct lsm_context *cp) } EXPORT_SYMBOL(security_inode_notifysecctx); +/* + * The inode_[gs]etsecctx functions need to proved a context + * for multiple security modules. If there is more than one + * LSM supplying hooks the format will be + * lsm1='value',lsm2='value'[,lsmN='value']... + */ +static void lsm_release_secctx(struct lsm_context *cp) +{ + kfree(cp->context); +} + int security_inode_setsecctx(struct dentry *dentry, struct lsm_context *cp) { - return call_int_hook(inode_setsecctx, 0, dentry, cp); + struct security_hook_list *hp; + struct lsm_context lc; + char *full; + char *ctx; + char *quote; + int rc = 0; + + if (lsm_inode_secctx_count <= 1) + return call_int_hook(inode_setsecctx, 0, dentry, cp); + + full = kstrndup(cp->context, cp->len, GFP_KERNEL); + if (full == NULL) + return -ENOMEM; + + ctx = full; + hlist_for_each_entry(hp, &security_hook_heads.inode_setsecctx, list) { + if (strncmp(ctx, hp->lsm, strlen(hp->lsm))) { + WARN_ONCE(1, "security_inode_setsecctx form1 error\n"); + rc = -EINVAL; + break; + } + ctx += strlen(hp->lsm); + if (ctx[0] != '=' || ctx[1] != '\'') { + WARN_ONCE(1, "security_inode_setsecctx form2 error\n"); + rc = -EINVAL; + break; + } + ctx += 2; + quote = strnchr(ctx, cp->len, '\''); + if (quote == NULL) { + WARN_ONCE(1, "security_inode_setsecctx form3 error\n"); + rc = -EINVAL; + break; + } + quote[0] = '\0'; + if (quote[1] != ',' && quote[1] != '\0') { + WARN_ONCE(1, "security_inode_setsecctx form4 error\n"); + rc = -EINVAL; + break; + } + lc.context = ctx; + lc.len = strlen(ctx); + + ctx = quote + 2; + + rc = hp->hook.inode_setsecctx(dentry, &lc); + if (rc) + break; + } + + kfree(full); + return rc; } EXPORT_SYMBOL(security_inode_setsecctx); int security_inode_getsecctx(struct inode *inode, struct lsm_context *cp) { - return call_int_hook(inode_getsecctx, -EOPNOTSUPP, inode, cp); + struct security_hook_list *hp; + struct lsm_context lc; + char *final = NULL; + char *tp; + int rc; + + if (lsm_inode_secctx_count <= 1) + return call_int_hook(inode_getsecctx, -EOPNOTSUPP, inode, cp); + + hlist_for_each_entry(hp, &security_hook_heads.inode_getsecctx, list) { + rc = hp->hook.inode_getsecctx(inode, &lc); + if (rc) { + kfree(final); + return rc; + } + if (final) { + tp = kasprintf(GFP_KERNEL, "%s,%s='%s'", final, + hp->lsm, lc.context); + kfree(final); + } else + tp = kasprintf(GFP_KERNEL, "%s='%s'", hp->lsm, + lc.context); + security_release_secctx(&lc); + if (tp == NULL) { + kfree(final); + return -ENOMEM; + } + final = tp; + } + cp->context = final; + cp->len = strlen(final); + cp->release = lsm_release_secctx; + return 0; } EXPORT_SYMBOL(security_inode_getsecctx);