From patchwork Tue Sep 27 19:53:56 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 1683521 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=2620:137:e000::1:20; helo=out1.vger.email; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=yahoo.com header.i=@yahoo.com header.a=rsa-sha256 header.s=s2048 header.b=FyANs4HQ; dkim-atps=neutral Received: from out1.vger.email (out1.vger.email [IPv6:2620:137:e000::1:20]) by legolas.ozlabs.org (Postfix) with ESMTP id 4McVs83hCpz1yq3 for ; Wed, 28 Sep 2022 06:02:20 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232565AbiI0UCR (ORCPT ); Tue, 27 Sep 2022 16:02:17 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54002 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232475AbiI0UBv (ORCPT ); Tue, 27 Sep 2022 16:01:51 -0400 Received: from sonic306-27.consmr.mail.ne1.yahoo.com (sonic306-27.consmr.mail.ne1.yahoo.com [66.163.189.89]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0CD8F1DADDC for ; Tue, 27 Sep 2022 13:01:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1664308870; bh=seCOINmonPQSGntE/E8xcjVf/9OCNb6fA3lPm2KdU80=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject:Reply-To; b=FyANs4HQA4rJzvKsRILpfIz8jSred9wXLftxonTlWelgZu9h/C6TXs/xHtqGlRJWga2/i2H4r4s8lSwttx6YY4iUFfKcDzdZNsq+a/AxzmwoS7Iv/Me54oyYxdbzHkH3yTTbO7VcpFDvG8m6Tt5BrfGYJmwqVW42vV8+qWXpInpLHBHK9kvYSSKsgp2NhdYLLogmIKK1rz3EwrUti6IM4nnojqHKv5t0Z8iONrz65eQ3ibX2PUkla+0z38hujJpMM6BVhn8FibXxv4PxPDz7KjRcJSzLYRXeG7L36T1EcLf6yHuWRSbFQgQCw6+cJfBWuhV9f8m3juceR9Ofq1ekJw== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1664308870; bh=iztO2S6w6r/nQr5zYudlmrPAyiYnUBLn9uuVK6+KZH6=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=mVK48TyuhdqV245hN5IFh+lOCzGR8i/SMtyVKQTjnB+0xkCsUXG1RoG81WJOUCDfkgjIH0+L7mDfGZeOQwH8nTdjfWgZFCO2t/waYj52IN+UaVUK/n5l/fy+phE7136UWlWzRGkC1zlzqgNR+goBdWOtuWexSi7q44rQvES3F+UqTAStU/AU9nRNUdRjTfgjGfeUo0hEvlCbV/MV5rjIOGAMJB/pd58YJI2YILQn28MJzX9VoE9sS4P5aIUoABHuhKQH5FvrLyRZxh3PF/QCReLxRDVJmyjz5XXLsBLKGFGVCd13EOW+R2aMSyQ2ImriyBoU/U8H/0DHQCrHoEghBw== X-YMail-OSG: PtVHTAUVM1nqXZ3sFGdaogjiDnDjBqCNkbGV_DIUH_PIAxTFFWeD4xJQJG_oz2T YOBlKNXJ0gUKZtnrD0Q5G5ZdWOtc5YL.iu5qnCCo5JQbv0iTDwHxHWOBiQ3eRmnL2bHe79Zt8bkA 0nTk7OdP05MzpHMpwRILv3wXjB18i3RO6w8axqwASN8pWHwhzitDPILARG1vOz037U7_yEuwcEto BQt0UTmvijBdlLCDcTNB.8YhHPkPHGKA7ogqLChAtHnZ5E45aXtcHp2LLy7jpM.Zg_NLXLKaufcM VfIHUgGZjulkrsHMPpYcg6QUrGEfmBRkR8Y4oJNGOt4pSVN9eGIObwxnx9R._Nmx55xgUS_DRwqj 30RhOHlF2MjAitJbtiYsBSaIk8ScEywt6Y2OyVd3wjCETnGRJPZkKwIvo56ZQOR6KwFvmzc52cr5 cI6B5mGQz6Zcw6uKuZjpspUledpbNbIHVCvq_pXcxV.LvtL4VXRw3wTCUkh5B8oSGuG_yl1sJ4.w dhdTUFkMy2iXA.cx60Y42OTA7fxeRk.40p2868yPG6A_mjhaE8FFX6GPd94qyYz38_yis3NTan4n pEVMVP00OeLBA7uv8ywQewkxdZVQ1dY70LbDYIvkbWsgZ0rIfYrdk1XDeTFRLdFbCkWSUnCZ1SLM EPn0VPuvXShM9bBOLNxK0IZckFn8m1xkmiYwH2cSafX6cCx3BAxNzc73s9d6suLKs7rLpMvtChPx fQjwbdkEnU6DL6rQd9ImyxqH.PEEB3WqMhzIlQI3_KGcX1FT3N_R4vPoRz5cowRgKUtsSthrJDl6 eVanbnsYbMeBf8q7fCYq0GXfXmQWQPD20gXLpk4Duyha5BU7nfUHXTv4oLsIeSJvtPfhd0tdLkVi 1hiecaML8upOxfgztY7J8HZnTNQJtiDDHjNqy3P5xS.zizecIgQany7he.En5IuTbQjrWX1ckaaA v9K.hkOZ3Nk1UUt.vkFvAW7S9ricvMbTvxQscbKQaFjBlE8InJwkG45VCYHDr5K2fKhRLSZRm5hQ Rl4hrDMGBK9VKL_qfeNFOuuzePEgbcNATSGN6kOrYHXszCYDeQhzNbz4M9yBNNYu65NWWL46AzWG Am1LXsWX4UMmAR9ySvY3VvKOAzu5EUNY.ynSphhwFQhNzG9_pqf7ujRVfv_hgFJcNrh.Cwo2pyhe h2hsiuiNNLPJRBEgLAjdtXHKPOJOj02.QL6TdmG_7vRoW8Q1KJuMOB6ScRX_RegBxxMU1ZwPXNmI RMBotC.ppKbJPyAqDsaik0dJBfRIWg4MgHea75V41sfkWsv0l5P0t_qWWZ_qHHMP2nvcQPNVh3gu lucr3GUDEm00awGOA5aeuKi3kClQ1QQwpK_fWHnUIDHc0sdZuyMGR7D6Spf3aLAwZXfw_qb3l4zd CHN44wmvILfmbx01Wh1oPeZm9xOGbyGCblLD8x4uZLhHAuX0zc.egpbTX.rCl2w3m9ugKKWip_BR WS3Y70XSWW8tH._Tga8CPt5KiVKam2ABRPAP6ZH7DRj0q1Vs6UPnbYBQf9pb8Iol1BxJS__OXfXJ Lf58yb1Z.rX1O_OB_.G6KLdxifpFI3Ccx_mAyDud2HZBPp5k29AAIk5qhjIutF316nxyaBPetwXL NaMi3agloJG9a8OVBB5Q9h2a8f0i24DpDNjg6nE0MxBADu9d1zfrZwHo7ZTAFG3l.B4ybcGJErzz 7Aj7xoVW19Ch1.VPQEvRV11tD.IoMn6unt6vff3nIw31eRE4dt93KBrwfwf.Y4_71lOSr8e7VHdb 10nQSOctIgJqzGT1qsl0I_WKLvcizNLEB8DLVfG1JWc6hc3GnSoZLGN_62zSvK2KC4IkxDLulzcS CxCav3oRyLRAvheFBWeIEYJcmrFGP7s03_RYVTW_jd.vS1rqLMT8RXeX9oL9gMBI2OqdwMW05NWF Bzf.ULl_0KhFylNvAXfL2T2VjaOfemuq61Bml8p41wQuhaty5IDsq5NLyyab8Ps4iEdHgWn0ezr. lNixR17.vLtUEcEHgiiqJrYHD5qV9tWw_u5jwALLY2cch6sFhcvrY4.ddOquzb3i0fOi9Wh7fR8O ofsk7xd0ZVEb9eCaFKBsGd5VYfhBlxukFe7N8I6SrF9PvaybijiarOlgT.tYi_oRjijUMmZATCOR _KkzDuflWM7LfRfcILbGH6_x9gpPaT4OiicjECa._Bkj3vN3NTWyUYoVeWiOJaREHqLrVgR7VN87 DUtZCP5Vie2FAztxTTNq99Pai8all3197fldchdUG1_rKxsKMy.agWDgfeKGio7QCv83x9jSB2MR bBufaBRCd_VghChO4.fezrDyXiM7ltYU0ApCRSEynJ4RsKbucWiYqxRU8rROeV7xx3w-- X-Sonic-MF: Received: from sonic.gate.mail.ne1.yahoo.com by sonic306.consmr.mail.ne1.yahoo.com with HTTP; Tue, 27 Sep 2022 20:01:10 +0000 Received: by hermes--production-bf1-759bcdd488-mc79z (Yahoo Inc. Hermes SMTP Server) with ESMTPA ID 6e213c213e954b1fa721ede3259fc3d6; Tue, 27 Sep 2022 20:01:07 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, paul@paul-moore.com, linux-security-module@vger.kernel.org Cc: casey@schaufler-ca.com, linux-audit@redhat.com, jmorris@namei.org, selinux@vger.kernel.org, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, stephen.smalley.work@gmail.com, linux-kernel@vger.kernel.org, netdev@vger.kernel.org, netfilter-devel@vger.kernel.org Subject: [PATCH v38 14/39] LSM: Use lsmblob in security_secctx_to_secid Date: Tue, 27 Sep 2022 12:53:56 -0700 Message-Id: <20220927195421.14713-15-casey@schaufler-ca.com> X-Mailer: git-send-email 2.37.3 In-Reply-To: <20220927195421.14713-1-casey@schaufler-ca.com> References: <20220927195421.14713-1-casey@schaufler-ca.com> MIME-Version: 1.0 X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_NONE autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org Change the security_secctx_to_secid interface to use a lsmblob structure in place of the single u32 secid in support of module stacking. Change its callers to do the same. The security module hook is unchanged, still passing back a secid. The infrastructure passes the correct entry from the lsmblob. Acked-by: Paul Moore Reviewed-by: Kees Cook Signed-off-by: Casey Schaufler Cc: netdev@vger.kernel.org Cc: netfilter-devel@vger.kernel.org To: Pablo Neira Ayuso --- include/linux/security.h | 26 ++++++++++++++++++-- kernel/cred.c | 4 +--- net/netfilter/nft_meta.c | 10 ++++---- net/netfilter/xt_SECMARK.c | 7 +++++- net/netlabel/netlabel_unlabeled.c | 23 +++++++++++------- security/security.c | 40 ++++++++++++++++++++++++++----- 6 files changed, 85 insertions(+), 25 deletions(-) diff --git a/include/linux/security.h b/include/linux/security.h index e95801437328..0134a938fd65 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -218,6 +218,27 @@ static inline bool lsmblob_equal(const struct lsmblob *bloba, extern int lsm_name_to_slot(char *name); extern const char *lsm_slot_to_name(int slot); +/** + * lsmblob_value - find the first non-zero value in an lsmblob structure. + * @blob: Pointer to the data + * + * This needs to be used with extreme caution, as the cases where + * it is appropriate are rare. + * + * Return the first secid value set in the lsmblob. + * There should only be one. + */ +static inline u32 lsmblob_value(const struct lsmblob *blob) +{ + int i; + + for (i = 0; i < LSMBLOB_ENTRIES; i++) + if (blob->secid[i]) + return blob->secid[i]; + + return 0; +} + /* These functions are in security/commoncap.c */ extern int cap_capable(const struct cred *cred, struct user_namespace *ns, int cap, unsigned int opts); @@ -549,7 +570,8 @@ int security_setprocattr(int lsmid, 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_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); int security_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen); @@ -1411,7 +1433,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 3925d38f49f4..adea727744f4 100644 --- a/kernel/cred.c +++ b/kernel/cred.c @@ -791,14 +791,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 55d2d49c3425..2c6edee9fbea 100644 --- a/net/netfilter/nft_meta.c +++ b/net/netfilter/nft_meta.c @@ -851,21 +851,21 @@ 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) + if (!lsmblob_is_set(&blob)) return -ENOENT; - err = security_secmark_relabel_packet(tmp_secid); + err = security_secmark_relabel_packet(lsmblob_value(&blob)); if (err) return err; - priv->secid = tmp_secid; + priv->secid = lsmblob_value(&blob); return 0; } diff --git a/net/netfilter/xt_SECMARK.c b/net/netfilter/xt_SECMARK.c index 498a0bf6f044..87ca3a537d1c 100644 --- a/net/netfilter/xt_SECMARK.c +++ b/net/netfilter/xt_SECMARK.c @@ -42,13 +42,14 @@ secmark_tg(struct sk_buff *skb, const struct xt_secmark_target_info_v1 *info) static int checkentry_lsm(struct xt_secmark_target_info_v1 *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", @@ -56,6 +57,10 @@ static int checkentry_lsm(struct xt_secmark_target_info_v1 *info) return err; } + /* xt_secmark_target_info can't be changed to use lsmblobs because + * it is exposed as an API. Use lsmblob_value() to get the one + * value that got set by security_secctx_to_secid(). */ + info->secid = lsmblob_value(&blob); 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 0555dffd80e0..87fb0747d3e9 100644 --- a/net/netlabel/netlabel_unlabeled.c +++ b/net/netlabel/netlabel_unlabeled.c @@ -880,7 +880,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 @@ -904,13 +904,18 @@ 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; + /* netlbl_unlhsh_add will be changed to pass a struct lsmblob * + * instead of a u32 later in this patch set. security_secctx_to_secid() + * will only be setting one entry in the lsmblob struct, so it is + * safe to use lsmblob_value() to get that one value. */ + return netlbl_unlhsh_add(&init_net, - dev_name, addr, mask, addr_len, secid, - &audit_info); + dev_name, addr, mask, addr_len, + lsmblob_value(&blob), &audit_info); } /** @@ -931,7 +936,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 @@ -953,13 +958,15 @@ 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; + /* security_secctx_to_secid() will only put one secid into the lsmblob + * so it's safe to use lsmblob_value() to get the secid. */ return netlbl_unlhsh_add(&init_net, - NULL, addr, mask, addr_len, secid, - &audit_info); + NULL, addr, mask, addr_len, + lsmblob_value(&blob), &audit_info); } /** diff --git a/security/security.c b/security/security.c index ca749a8f36b8..0c5be69d8146 100644 --- a/security/security.c +++ b/security/security.c @@ -2228,10 +2228,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); @@ -2382,10 +2394,26 @@ 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, + u32 *secid) { - return call_int_hook(socket_getpeersec_dgram, -ENOPROTOOPT, sock, - skb, secid); + struct security_hook_list *hp; + int rc = -ENOPROTOOPT; + + /* + * Only one security module should provide a real hook for + * this. A stub or bypass like is used in BPF should either + * (somehow) leave rc unaltered or return -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, secid); + if (rc != -ENOPROTOOPT) + break; + } + return rc; } EXPORT_SYMBOL(security_socket_getpeersec_dgram); From patchwork Tue Sep 27 19:53:57 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 1683522 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=2620:137:e000::1:20; helo=out1.vger.email; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=yahoo.com header.i=@yahoo.com header.a=rsa-sha256 header.s=s2048 header.b=Zsf4Uk9S; dkim-atps=neutral Received: from out1.vger.email (out1.vger.email [IPv6:2620:137:e000::1:20]) by legolas.ozlabs.org (Postfix) with ESMTP id 4McVvd27h8z1yq3 for ; Wed, 28 Sep 2022 06:04:29 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232476AbiI0UEY (ORCPT ); Tue, 27 Sep 2022 16:04:24 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39550 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232158AbiI0UD7 (ORCPT ); Tue, 27 Sep 2022 16:03:59 -0400 Received: from sonic304-28.consmr.mail.ne1.yahoo.com (sonic304-28.consmr.mail.ne1.yahoo.com [66.163.191.154]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 055B81C99DA for ; Tue, 27 Sep 2022 13:02:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1664308964; bh=IyZSFo5018fj4sTvPWuUspKouZDyi3IU5Yce539hXgo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject:Reply-To; b=Zsf4Uk9SPwAp/rtvZyudJITGQRcRDRzaRRMmUV/Qbdvi64k/TtJlUMgnOPBXGjK4ef1beycZVaBzaw2h6bv2VFSUI2Kuqnthvjhl3GyMbuCQFU3Vra4ajDshKw/p/OIl8Hl1vJ8UIGjgmokWbHiHq5EXHNw89HRNdP0qUOBSa//bqen5CPq1Gl/aAc4Tj70srdQCO3JalTfsPSP2BS003tpxvA4eh5n6cGMDnzoCUEdIUAXSzF6t5/kUbWx+VCmnjSz5Sv4/z7Qr21PX02MkNZC6IUQWD5/UmzUzd3huJODgOl/rgoLz831f3+WLwNZzjCcK9YOwAnj586LVs20qFQ== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1664308964; bh=VPXvNrSUjp4CnrAKblZ28b+IHaBf8LADSG69L1xOBpK=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=XLdARf5vdWEPOWQCwEnzvDIf2bf9nJWfE7ercMpNSeDdvGN+W7Gr7rIpaPdUmv+BeeWuT9u3FSIoGbcFgjGSkA6Xk6clMj/BVKQ3FEYKYdNt+CDGtNo8TyH1iH+hcr6Zk5mHW5Y/VJ92zOZAaqyiLVcnGwpOn2TnBOejFsCFYlwqfvcYTjZitXXKQJ8y0APT+3PLMOa1hrJqS3wtnh/1xY31C3gwYsNkprz7ZbBZ5KboMVV8meHaJRWvOUniUV89oCxU1Lak4+OvbQXRn+rrxsICRQvyQ9qQJOiYvnpYUbODqLxQEGK2htvUQQ4gv+ueoMpSt1MZesC1z4yPKtkjpw== X-YMail-OSG: I6PNIdEVM1lj8uGHiWPC_bv.uBFGppAnMsVPO1J74p.XgB2MX0L.qgOkY_KFiGL fBkXYtjfGVyKENrQa.dk.WOKest52zix3F6Ent.OgUUGIR7GRNvMQSHb6s08iUPAfZ7R0yDw444m 8e59xrL_I3K6QdJDVJSZYzPhiGmJ87mW_N6nbiYcY5.esyqinLKn70ucjXxTXA1bt58HGH_y6Kl7 Zj._ecm7erB24n9WHEybl052Cej0cBN_Uz9MVL5hkX1S.gwom.UCSn2DTisn6bAA_Oe8eOwzdgxd q5YJCPuO7SW1aurOo.fqNNWYJzwBi_EAHtNsf._ujv8xLqQa5T51N7vgGWqQ_izOlfFI2NiewBya zu1RP2swhUNfx9nF3Ec1AAFLSigvY66MY8YLa6Hef9Muxo98.L993bumk5CkWZaZiOtcnTGhFBYR 085wTta75vlH4Y2O0sMEywt4zN9.olTI.tvvPVMUgSVq5CdpChO.FG.HTcKCBFTA8MBUHvsS4rZE _KZ2x.eBCcWdmQw4s5fANC19RG.SrMTXdKessHuNXyukah2WrH8yz_4iJ2BDDO2LglhW1LGWTs5m pG.ezruvmksrG_BtU58eKjRB4XGC46QHlFEwLzk7WSqzgHxlSDIm22kD0mUFv8bH4JSyybGCsTBs GX.hf3CilczHZzeBmcwzpf0ISnjTQ4FtKGJABCYf2bTi6Pzz1jr7OGhXqb40CEIw5v8rAWX1Ishe qrVJtS71sVOgp1.JktmGmol4f9uY0bLMbUTXi3oWN91nsPYU1U7s7Rt3.ai4ui68NvePfiC5g7RI jrmAblot6XN7ks8XHPjuUgACgbhPo_CDK7XT6J4GWTZsCuqNYFeHSPMm6RYKKbY7WFPEc1eU8m6j yNeSQDmficD_zfZCb_EjFWANbnigkPhNcx6m15ti4RPEFE8_M9m92rlbf437RIwVPI1uFB7Y8S8s i_rNJQSb7xNq4NpFXUk.O52qKtPE259V3HsPV6lpA6lSbn0DbtjrSDcyB.RvexUFA3XC892c9Fy3 8kezpSX3sN_DTa8QRb8YTuD6n2ui2.b2x5mH5yyRGI.GB.CRDUTM5iQKYBwY7GLHq59pXt0zihW1 I.9YeW5aTftukKzr9SNHGMLDpQfLQCE5hgKUK7_K5MI7sGX_O_MPeElaaEeOdcG9MGBx0BjNTzB1 dAA9dWnYcQ7r_wLaRpeWwRWbhzQ9OhBlwCs5o3eyJ78Fe8YDhd8AE4NZOtx0FtMvKOYQIIkndJzS ZHOlTMlA5syEIy2UW1vXVIiyAA_NhEJEiE5OzvA6hu4uHupWyRIr9SOsODsNIqP7IRUtVc88BVbg iqqJvi_DVeEBWEjDnoJ_MVFDbZhiWyxaPnwoUlz12b0wKyoVWIc5KxtvJDmzUwgpkWQv8c.amzsB 6pGY0LV21yMI9QSbG_Pcy.nAbnBU19Z9bCO5_ijsFJ9CPs5FAd.D2KiN4lZiVsKtzYNlrKX4Vg1L 6GJcrDzluI.PxmkuWHrrdfeO_clCgU8bU9dyMkpOtkiIUXV8fajkX80BLmM6a86ge98.8WpQpXrL xY6fVICmBr4qM84j0D.npYUoiX7ja1eAF4TW09.spNBxBtzxo6XE9PEDXE2q0z1ebnXnVjQw6Kbq p5AqnUXNccU9wkL7kJ1BmG_gy3QFoCfvHH2Y31X7cWd0oCPLWHR8Xyd4W9MQN0_wn.JeJbpZYFjE K3epA5KI6JlIf92irtSfSeUhUe66a8UyW5uNrin8cyR6aO361ns19b7Wd_foA3HkZFECSYzvvCvz faY8Bfc7.xmVn5.2a.sprWNA0EHqzWAxhNPnCf.fTJ4V1KtcYBbuQhAQF46sBe6DKmDb6Du2HAQj eAKxfDi.En4l6lj67UTVdx_RQBK_RgUfdKXDw1Gp9PVYVjVRup4dE25iH1YZICiFqPab.G38XknV ypPflG9hIOJfMHnGV1HI_oeEW3oIhxkI0Vj6W.Ct6qhwY5.UG8ndRUDTC.SZ1CWbgImjtKMFCvkk PxpM2UmzPRPFNcE7cwA2P0Uctk4QXfjc_jwIxdfb3bmkxtHlV8qHZyg8Ld42TE4pTn9BN2Vd2s0l OXkOrWxpt3fSquMF_23YFmAHpMTakSrewLOA3OYupxB4nZ6Y0nPDgQxuGT.WkmyTEhfOqxvjHcrE 6X_Rv.AEeCUhUKuxoC1JcfFgYl5HJoBJrFMHZA51rI.GvVOecf9SM0BueKzvvRm_Ekb8cN3EcwlL Ouijs2i8.jwUW1C73Zau70ILmuk4iJBH2Toy1OviLNp5Dt6E1_TWBOitdqpux61idzmy9cq9jXB4 xWxTcDwsAXA_j X-Sonic-MF: Received: from sonic.gate.mail.ne1.yahoo.com by sonic304.consmr.mail.ne1.yahoo.com with HTTP; Tue, 27 Sep 2022 20:02:44 +0000 Received: by hermes--production-ne1-6dd4f99767-97ndb (Yahoo Inc. Hermes SMTP Server) with ESMTPA ID 0896e936b45c39858cb958d2af309d20; Tue, 27 Sep 2022 20:02:41 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, paul@paul-moore.com, linux-security-module@vger.kernel.org Cc: casey@schaufler-ca.com, linux-audit@redhat.com, jmorris@namei.org, selinux@vger.kernel.org, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, stephen.smalley.work@gmail.com, linux-kernel@vger.kernel.org, netdev@vger.kernel.org, netfilter-devel@vger.kernel.org Subject: [PATCH v38 15/39] LSM: Use lsmblob in security_secid_to_secctx Date: Tue, 27 Sep 2022 12:53:57 -0700 Message-Id: <20220927195421.14713-16-casey@schaufler-ca.com> X-Mailer: git-send-email 2.37.3 In-Reply-To: <20220927195421.14713-1-casey@schaufler-ca.com> References: <20220927195421.14713-1-casey@schaufler-ca.com> MIME-Version: 1.0 X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_NONE autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@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. Acked-by: Paul Moore Reviewed-by: Kees Cook Signed-off-by: Casey Schaufler Cc: netdev@vger.kernel.org Cc: linux-audit@redhat.com Cc: netfilter-devel@vger.kernel.org To: Pablo Neira Ayuso --- drivers/android/binder.c | 12 +++++++++- include/linux/security.h | 5 +++-- include/net/scm.h | 7 +++++- kernel/audit.c | 21 +++++++++++++++-- kernel/auditsc.c | 27 ++++++++++++++++++---- net/ipv4/ip_sockglue.c | 4 +++- net/netfilter/nf_conntrack_netlink.c | 14 ++++++++++-- net/netfilter/nf_conntrack_standalone.c | 4 +++- net/netfilter/nfnetlink_queue.c | 11 +++++++-- net/netlabel/netlabel_unlabeled.c | 30 +++++++++++++++++++++---- net/netlabel/netlabel_user.c | 6 ++--- security/security.c | 11 +++++---- 12 files changed, 123 insertions(+), 29 deletions(-) diff --git a/drivers/android/binder.c b/drivers/android/binder.c index 6428f6be69e3..34602b68d2a1 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -3170,10 +3170,20 @@ static void binder_transaction(struct binder_proc *proc, if (target_node && target_node->txn_security_ctx) { u32 secid; + struct lsmblob blob; size_t added_size; security_cred_getsecid(proc->cred, &secid); - ret = security_secid_to_secctx(secid, &secctx, &secctx_sz); + /* + * Later in this patch set security_task_getsecid() will + * provide a lsmblob instead of a secid. lsmblob_init + * is used to ensure that all the secids in the lsmblob + * get the value returned from security_task_getsecid(), + * which means that the one expected by + * security_secid_to_secctx() will be set. + */ + lsmblob_init(&blob, secid); + ret = security_secid_to_secctx(&blob, &secctx, &secctx_sz); if (ret) { binder_txn_error("%d:%d failed to get security context\n", thread->pid, proc->pid); diff --git a/include/linux/security.h b/include/linux/security.h index 0134a938fd65..d9ab76c909e0 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -569,7 +569,7 @@ int security_getprocattr(struct task_struct *p, int lsmid, char *name, int security_setprocattr(int lsmid, 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); @@ -1426,7 +1426,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 1ce365f4c256..23a35ff1b3f2 100644 --- a/include/net/scm.h +++ b/include/net/scm.h @@ -92,12 +92,17 @@ 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 lsmblob lb; char *secdata; u32 seclen; int err; if (test_bit(SOCK_PASSSEC, &sock->flags)) { - err = security_secid_to_secctx(scm->secid, &secdata, &seclen); + /* There can only be one security module using the secid, + * and the infrastructure will know which it is. + */ + lsmblob_init(&lb, scm->secid); + err = security_secid_to_secctx(&lb, &secdata, &seclen); if (!err) { put_cmsg(msg, SOL_SOCKET, SCM_SECURITY, seclen, secdata); diff --git a/kernel/audit.c b/kernel/audit.c index a75978ae38ad..6aa7db400d10 100644 --- a/kernel/audit.c +++ b/kernel/audit.c @@ -1464,7 +1464,16 @@ 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 sets all values in the lsmblob + * to audit_sig_sid. This is temporary until + * audit_sig_sid is converted to a lsmblob, which + * happens later in this patch set. + */ + lsmblob_init(&blob, audit_sig_sid); + err = security_secid_to_secctx(&blob, &ctx, &len); if (err) return err; } @@ -2170,12 +2179,20 @@ int audit_log_task_context(struct audit_buffer *ab) unsigned len; int error; u32 sid; + struct lsmblob blob; security_current_getsecid_subj(&sid); if (!sid) return 0; - error = security_secid_to_secctx(sid, &ctx, &len); + /* + * lsmblob_init sets all values in the lsmblob to sid. + * This is temporary until security_task_getsecid is converted + * to use a lsmblob, which happens later in this patch set. + */ + 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 5fab2367bfd0..d083c050d660 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -679,6 +679,13 @@ static int audit_filter_rules(struct task_struct *tsk, security_current_getsecid_subj(&sid); need_sid = 0; } + /* + * lsmblob_init sets all values in the lsmblob + * to sid. This is temporary until + * security_task_getsecid() is converted to + * provide a lsmblob, which happens later in + * this patch set. + */ lsmblob_init(&blob, sid); result = security_audit_rule_match(&blob, f->type, f->op, @@ -695,6 +702,13 @@ static int audit_filter_rules(struct task_struct *tsk, if (f->lsm_str) { /* Find files that match */ if (name) { + /* + * lsmblob_init sets all values in the + * lsmblob to sid. This is temporary + * until name->osid is converted to a + * lsmblob, which happens later in + * this patch set. + */ lsmblob_init(&blob, name->osid); result = security_audit_rule_match( &blob, @@ -1093,6 +1107,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) @@ -1102,7 +1117,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 { @@ -1393,8 +1409,10 @@ static void show_special(struct audit_context *context, int *call_panic) if (osid) { char *ctx = NULL; u32 len; + struct lsmblob blob; - if (security_secid_to_secctx(osid, &ctx, &len)) { + lsmblob_init(&blob, osid); + if (security_secid_to_secctx(&blob, &ctx, &len)) { audit_log_format(ab, " osid=%u", osid); *call_panic = 1; } else { @@ -1560,9 +1578,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 e49a61a053a6..bb8e2af31d4f 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 lsmblob lb; char *secdata; u32 seclen, secid; int err; @@ -138,7 +139,8 @@ static void ip_cmsg_recv_security(struct msghdr *msg, struct sk_buff *skb) if (err) return; - err = security_secid_to_secctx(secid, &secdata, &seclen); + lsmblob_init(&lb, secid); + 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 7562b215b932..2e257aa4f61b 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -347,8 +347,13 @@ 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() puts ct->secmark into all of the secids in blob. + * security_secid_to_secctx() will know which security module + * to use to create the secctx. */ + lsmblob_init(&blob, ct->secmark); + ret = security_secid_to_secctx(&blob, &secctx, &len); if (ret) return 0; @@ -656,8 +661,13 @@ 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() puts ct->secmark into all of the secids in blob. + * security_secid_to_secctx() will know which security module + * to use to create the secctx. */ + 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 4ffe84c5a82c..da61eb8cde76 100644 --- a/net/netfilter/nf_conntrack_standalone.c +++ b/net/netfilter/nf_conntrack_standalone.c @@ -178,8 +178,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 87a9009d5234..bc25d49575e4 100644 --- a/net/netfilter/nfnetlink_queue.c +++ b/net/netfilter/nfnetlink_queue.c @@ -305,13 +305,20 @@ 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() puts ct->secmark into all of the secids in + * blob. security_secid_to_secctx() will know which security + * module to use to create the secctx. */ + 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 87fb0747d3e9..980ad209b57e 100644 --- a/net/netlabel/netlabel_unlabeled.c +++ b/net/netlabel/netlabel_unlabeled.c @@ -376,6 +376,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)) @@ -438,7 +439,11 @@ 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() puts secid into all of the secids in blob. + * security_secid_to_secctx() will know which security module + * to use to create the secctx. */ + lsmblob_init(&blob, secid); + if (security_secid_to_secctx(&blob, &secctx, &secctx_len) == 0) { audit_log_format(audit_buf, " sec_obj=%s", secctx); @@ -475,6 +480,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, @@ -493,8 +499,13 @@ static int netlbl_unlhsh_remove_addr4(struct net *net, (dev != NULL ? dev->name : NULL), addr->s_addr, mask->s_addr); dev_put(dev); + /* lsmblob_init() puts entry->secid into all of the secids + * in blob. security_secid_to_secctx() will know which + * security module to use to create the secctx. */ + 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); @@ -536,6 +547,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); @@ -553,8 +565,13 @@ static int netlbl_unlhsh_remove_addr6(struct net *net, (dev != NULL ? dev->name : NULL), addr, mask); dev_put(dev); + /* lsmblob_init() puts entry->secid into all of the secids + * in blob. security_secid_to_secctx() will know which + * security module to use to create the secctx. */ + 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); @@ -1080,6 +1097,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, @@ -1134,7 +1152,11 @@ static int netlbl_unlabel_staticlist_gen(u32 cmd, secid = addr6->secid; } - ret_val = security_secid_to_secctx(secid, &secctx, &secctx_len); + /* lsmblob_init() secid into all of the secids in blob. + * security_secid_to_secctx() will know which security module + * to use to create the secctx. */ + 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 3ed4fea2a2de..893301ae0131 100644 --- a/net/netlabel/netlabel_user.c +++ b/net/netlabel/netlabel_user.c @@ -86,6 +86,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; @@ -98,10 +99,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 0c5be69d8146..9c49406e5ff9 100644 --- a/security/security.c +++ b/security/security.c @@ -2209,17 +2209,16 @@ 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) { struct security_hook_list *hp; int rc; - /* - * Currently, only one LSM can implement secid_to_secctx (i.e this - * LSM hook is not "stackable"). - */ hlist_for_each_entry(hp, &security_hook_heads.secid_to_secctx, list) { - rc = hp->hook.secid_to_secctx(secid, secdata, seclen); + 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 != LSM_RET_DEFAULT(secid_to_secctx)) return rc; } From patchwork Tue Sep 27 19:54:03 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 1683523 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=2620:137:e000::1:20; helo=out1.vger.email; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=yahoo.com header.i=@yahoo.com header.a=rsa-sha256 header.s=s2048 header.b=bZ5TnFZX; dkim-atps=neutral Received: from out1.vger.email (out1.vger.email [IPv6:2620:137:e000::1:20]) by legolas.ozlabs.org (Postfix) with ESMTP id 4McVzF5DX2z1yqD for ; Wed, 28 Sep 2022 06:07:37 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232877AbiI0UHe (ORCPT ); Tue, 27 Sep 2022 16:07:34 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44858 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232616AbiI0UGy (ORCPT ); Tue, 27 Sep 2022 16:06:54 -0400 Received: from sonic306-27.consmr.mail.ne1.yahoo.com (sonic306-27.consmr.mail.ne1.yahoo.com [66.163.189.89]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 295271E768E for ; Tue, 27 Sep 2022 13:06:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1664309160; bh=uT9reuuisT9bCYeVveRbY1qbZdIvJNHjxL5Je3V5MZc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject:Reply-To; b=bZ5TnFZXYmgCJVodsVCnz9Q07127jfS0iw9kZSI9yPVDXt3BTRGoz6Fi6SbcwfuA7V2861Lp2Mtusk9UpnSZm9kGl85dIpsITYj+eygjBhAUb86SK8O4hwKmCphT55IRpM9kZu0yOohoYoXvAcCtfaTWMH/FgUybgBEtyu9QvBfjqfZ1xuSzYQnIulP09htuqHkl4z+KJQfb1gm90G1RTPZvXqXOx6DQexbNBiMo87zdIr/yqZcHlqHL6OyAO43SSfOadwoZgPjoiTHYcQqWiB/Qi1LwOrlu/vNYvLSlTT0Tsdb7+MZOGJ/o6jx09hd1D+wlILufxnG4CXn+3T6MNA== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1664309160; bh=lKF4CFfgmBoEXxiwSEj9yTYGUD0Ozh47iP4Y2g8iC5C=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=co0PiQBhuvslcZzOaIwMiMsaFScrrnSw/2o/ZZzhBa4IfPVC0wfD9pIE0Jd/Kd08/ZxRr3+sf5oP5JxYedd4F6+LO/Ko6SBHpe8RO52pZQobVCX0lwWy14rITIYaMCVUPcQCSLXSLKOgksEihSIlfvhxqA3VKirle+4qwUyM04XNIUdS8g4kZlZ06cLclabC1SPRHL/8Ye9VOBafI3Bxe381ujucmN6wjXv8CTJM7QyWCFHgA4ljMWmk9KXQWrocV3g/JbX5DKCJnjDKUnEjDvkKg4qYaFjNop43Kfh4bv431iZVu6b7zEh8xB6aJ2dqzhTSJg6zSsR4l1i3Ht9C6A== X-YMail-OSG: kXmI0DMVM1kH1wVdIBLwGlobmJcVPO69YKYtPQFJazZBGrnemtOg3l3E.dUaKHM svOWV1Bh0ATyjhE7d9Zp3MhKOBdPIbQUrYG9Nr9oz0W0TZmi6PwyfsYwpmU4vENAp_nr6LAScdJy 8mtXlvZVpK2dLR35.MPVdNZmz8f2K6nb_BruxhAyd6iAaUmP0ZhyH1Hrf5it9aH3st_t7Jy_sXOQ _t0t0cGEqZWAr7euaMfyZsaU2FuVA5kmZ7cDcDAMSspNLH61qqJjjTieQjXI_r_lF9g3uIn4_Eze jkuNCxDSg.gFhe4ovOL8cCH6j_7K2nOlIEm_ajDVEAVrOmXH5jro3ZUCpgWr5FrWSxFWlUkgEiDb KTxGdiFKOWDpXNE1BtgCVp4qrNdb1kEuothaxdkh09XJfcsKIDjOoG8Dl5mK0lhfcF1y_Oj4uNxw yYoJU8PHNSBeKM1diq4hLdecdZMvaPMpC8gvkbMi7sZs9yL5ov91MN3jCM8lYkKk0Ce5H4MptcsM J83CsmyoYyE0au5aJ5_7OgOFOcC1lRqUj4OlJEoVdf.ZU102AUfN5y.C8ahU3NxxlAeXEujtv6Ue n8S8gmwV_wDQfB7kL6N3CiU_wGo4aZu6Rgk0pGSltUCKjJNjBIKd5I0amCUqHqkJr.BhGUTL.GFk smGKjBx2BzrQMfc5WdO2PsT_If4kXFqraQPFvFoJbM5NO9CpnCoRBbf3uk2YgmFZUG2NWATpMN5i r7Glml7gxFayfHo2TKtr5DThqrH31Ip7PnnC527Bmd9Lq4Z4Ht02TUMyp3tG7VcxEVAvOTczmRvF C5nVo3vl3UHk1Xvsp_8fQ9.fNPtQ_3T1nPo3zvom2DMcQ3vxXkQMPFQu3KKzulS_fh2_lKUHGPMS dn4HxL5gOXd5rg.o6rKdmCQWKvmmmsEyqvNutb20wm6NcdAOTCHhUcBnh1MYbRZRh5VnHglPBL_m x1qrXBkRnJP8gpk0PTbid3GsC7r0eTmxzFWd9t1vyA15XfNBfn01aBenjqMAC3KqrIRoI7UMi.hZ 5cqfe.ArCVV8pUKbRJHpJv.BdFYACwtUO1gMnGFuFQv8xar7A0rNQVEAgZSglvCssbE0zXRLFAdf 51l6QyuyABuGFtN4vWlsFrLK_G88I2heUuXBj3WwxS5nFCLU_UvrvijscaDkt1PxFnq9j2wPfXpS 0Cm3rJo9nrjBwiMmZkqcxfqTRYa956KcmNnAXgCdH9hqSe_HtuZbMyeR1I0pDDPtx.Yo_hU3qbtE wguD4KWdMkb8JDOIIgHVPbBjaGUyYrir6EKeTSa2vxDqJPjY_jxpqm0Eeh9odzkMOUQDWBVaH2W4 0Pu6JotuaRzgBEAISrJqsZDAijTG.Xu59X_mgznIghMK.v9ydGf7.KgRVXHzi.yziBtaH37LYqVL VZhVgMDUULhXvYuzQ92OdkbcRFO7mrrIF7lxDXFVWNOF.uY.xh7kA38blwkZbtiYy9b4yLbVHQls 4mJQjuDaL7pxLP2Rb1UXn7QL.qiOapkI85JmhKyy71p57dE9TOj1eTH4cDqGhtx.B1YmXhHxabtv 2dd7QoNPZ1AeBJfwnFU5KBviWabpilXUaN7TiEcSUBPV2G6O9HagHix5ABE7_epx6mIy7yOrM3LS 8BOxhdp8ELOIkf_qo8hgJuaQ8MIVu9St8nNuyyPUY2ljgWP.BZzv2ntFgwg_9QQX73gNTBChr5nj Xp14.HtQJ8T1B7QCOFjUSs2yJs6TnXg6Za9dQAJfrdwq8STkgI8sJzH7iDNyIBaweRXbkAPwCrCB ZTB5lGpHhc20UrfnbTm5BTN6ZUYZU4AsL0CkHiegxq9kc6ZMi9uUdP5Mt0jvWuBC5FFnx9.qPm0M ZSoq_N1eG_5lflIVI_90V7pZGtOqiD_CMyp4pKbpD2ffbsym.mbpnYKuTvVL6quWA3Z8f02m57UI sDfWoWMQNPxtmwsSY5mYzZRzfe8J6pSdWO.52D0RA8vo5H.4Loql6aRD_Xbi5k77AE3KvP0acV9B vtEJO6AHs7UkGKXsLbtq9thd01tbZUvstHpZ6T0qRJmmT4dYSED_sh8izOTinCciDFES39Pepsn9 q4LdUzfzLN6.UawfGR_0BnupQp5abhbSzAZOydtqU4fRDwoSjgOsRUcWJWxHyjSHrDh7P08lyYsg WfCuIEvavKJbNH2oITeUt7.dALrg5FNsdMBdYMOzZ1g3aTVtyqJFgVZXx_7dzN51RbutCEvgza0O qrld8p6.yiiSxhsMmoHgDPETIjaXsyvfxGeMatzseT9ESW_qPb88kVjYKhrKfzCReumwamspI377 Sn6wiLhknPQvbTZ7mPqF8U5Awh00EGpzBntcoS2EMgJLyrIIAxPTUFq4kj58Wwz9.cwQ- X-Sonic-MF: Received: from sonic.gate.mail.ne1.yahoo.com by sonic306.consmr.mail.ne1.yahoo.com with HTTP; Tue, 27 Sep 2022 20:06:00 +0000 Received: by hermes--production-gq1-7dfd88c84d-h7f6x (Yahoo Inc. Hermes SMTP Server) with ESMTPA ID f8e196d1098f8fc47a5a474327d019a8; Tue, 27 Sep 2022 20:05:55 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, paul@paul-moore.com, linux-security-module@vger.kernel.org Cc: casey@schaufler-ca.com, linux-audit@redhat.com, jmorris@namei.org, selinux@vger.kernel.org, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, stephen.smalley.work@gmail.com, linux-kernel@vger.kernel.org, Chuck Lever , linux-integrity@vger.kernel.org, netdev@vger.kernel.org, netfilter-devel@vger.kernel.org, linux-nfs@vger.kernel.org Subject: [PATCH v38 21/39] LSM: Ensure the correct LSM context releaser Date: Tue, 27 Sep 2022 12:54:03 -0700 Message-Id: <20220927195421.14713-22-casey@schaufler-ca.com> X-Mailer: git-send-email 2.37.3 In-Reply-To: <20220927195421.14713-1-casey@schaufler-ca.com> References: <20220927195421.14713-1-casey@schaufler-ca.com> MIME-Version: 1.0 X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_NONE autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@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 Acked-by: Paul Moore Acked-by: Stephen Smalley Acked-by: Chuck Lever Signed-off-by: Casey Schaufler Cc: linux-integrity@vger.kernel.org Cc: netdev@vger.kernel.org Cc: linux-audit@redhat.com Cc: netfilter-devel@vger.kernel.org To: Pablo Neira Ayuso Cc: linux-nfs@vger.kernel.org --- drivers/android/binder.c | 10 ++++--- fs/ceph/xattr.c | 6 ++++- fs/nfs/nfs4proc.c | 8 ++++-- fs/nfsd/nfs4xdr.c | 7 +++-- include/linux/security.h | 35 +++++++++++++++++++++++-- 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 | 11 ++++---- 15 files changed, 121 insertions(+), 35 deletions(-) diff --git a/drivers/android/binder.c b/drivers/android/binder.c index 6e1e35de1fcb..12aa3bea59ee 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -2898,6 +2898,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 */ struct list_head sgc_head; struct list_head pf_head; const void __user *user_buffer = (const void __user *) @@ -3231,7 +3232,8 @@ static void binder_transaction(struct binder_proc *proc, t->security_ctx = 0; WARN_ON(1); } - 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; @@ -3647,8 +3649,10 @@ static void binder_transaction(struct binder_proc *proc, binder_alloc_free_buf(&target_proc->alloc, t->buffer); err_binder_alloc_buf_failed: err_bad_extra_size: - 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/ceph/xattr.c b/fs/ceph/xattr.c index f31350cda960..d943be72dfff 100644 --- a/fs/ceph/xattr.c +++ b/fs/ceph/xattr.c @@ -1395,12 +1395,16 @@ int ceph_security_init_secctx(struct dentry *dentry, umode_t mode, void ceph_release_acl_sec_ctx(struct ceph_acl_sec_ctx *as_ctx) { +#ifdef CONFIG_CEPH_FS_SECURITY_LABEL + struct lsmcontext scaff; /* scaffolding */ +#endif #ifdef CONFIG_CEPH_FS_POSIX_ACL posix_acl_release(as_ctx->acl); posix_acl_release(as_ctx->default_acl); #endif #ifdef CONFIG_CEPH_FS_SECURITY_LABEL - security_release_secctx(as_ctx->sec_ctx, as_ctx->sec_ctxlen); + lsmcontext_init(&scaff, as_ctx->sec_ctx, as_ctx->sec_ctxlen, 0); + security_release_secctx(&scaff); #endif if (as_ctx->pagelist) ceph_pagelist_release(as_ctx->pagelist); diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 3ed14a2a84a4..47259990fae1 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -133,8 +133,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 1e9690a061ec..4a96e06f4827 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -2848,6 +2848,7 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp, int err; struct nfs4_acl *acl = NULL; #ifdef CONFIG_NFSD_V4_SECURITY_LABEL + struct lsmcontext scaff; /* scaffolding */ void *context = NULL; int contextlen; #endif @@ -3357,8 +3358,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 8d3b875cd04a..a3c11934620a 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -154,6 +154,37 @@ extern const char *const lockdown_reasons[LOCKDOWN_CONFIDENTIALITY_MAX+1]; extern int lsm_id; extern struct lsm_id *lsm_idlist[]; +/* + * 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; + cp->len = size; +} + /* * Data exported by the security modules * @@ -607,7 +638,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); int security_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen); @@ -1478,7 +1509,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 23a35ff1b3f2..f273c4d777ec 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; struct lsmblob lb; char *secdata; u32 seclen; @@ -106,7 +107,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 3d026013e6eb..d14e54098b9c 100644 --- a/kernel/audit.c +++ b/kernel/audit.c @@ -1214,6 +1214,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) @@ -1471,15 +1472,18 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) } sig_data = kmalloc(struct_size(sig_data, ctx, 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, struct_size(sig_data, ctx, len)); @@ -2171,6 +2175,7 @@ int audit_log_task_context(struct audit_buffer *ab) unsigned len; int error; struct lsmblob blob; + struct lsmcontext scaff; /* scaffolding */ security_current_getsecid_subj(&blob); if (!lsmblob_is_set(&blob)) @@ -2185,7 +2190,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 092aba46a9b3..8a16ed2f7206 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -1096,6 +1096,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; @@ -1113,7 +1114,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="); @@ -1373,6 +1375,7 @@ static void audit_log_time(struct audit_context *context, struct audit_buffer ** static void show_special(struct audit_context *context, int *call_panic) { + struct lsmcontext lsmcxt; struct audit_buffer *ab; int i; @@ -1407,7 +1410,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) { @@ -1569,6 +1573,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)) { @@ -1577,7 +1582,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 bb8e2af31d4f..030b8c3ffae0 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, secid; @@ -145,7 +146,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 2e257aa4f61b..2bf2673042f4 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -348,6 +348,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() puts ct->secmark into all of the secids in blob. * security_secid_to_secctx() will know which security module @@ -368,7 +369,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 da61eb8cde76..b0f4349ff88f 100644 --- a/net/netfilter/nf_conntrack_standalone.c +++ b/net/netfilter/nf_conntrack_standalone.c @@ -179,6 +179,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); @@ -187,7 +188,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 bc25d49575e4..1416f8b2fc83 100644 --- a/net/netfilter/nfnetlink_queue.c +++ b/net/netfilter/nfnetlink_queue.c @@ -397,6 +397,7 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue, enum ip_conntrack_info ctinfo = 0; const struct nfnl_ct_hook *nfnl_ct; bool csum_verify; + struct lsmcontext scaff; /* scaffolding */ char *secdata = NULL; u32 seclen = 0; ktime_t tstamp; @@ -634,8 +635,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: @@ -643,8 +646,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 604b9d1dd085..f62b88c85976 100644 --- a/net/netlabel/netlabel_unlabeled.c +++ b/net/netlabel/netlabel_unlabeled.c @@ -374,6 +374,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; @@ -447,7 +448,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); @@ -478,6 +481,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; @@ -508,7 +512,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); @@ -545,6 +551,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; @@ -574,7 +581,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); @@ -1093,6 +1101,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; @@ -1163,7 +1172,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 893301ae0131..ef139d8ae7cd 100644 --- a/net/netlabel/netlabel_user.c +++ b/net/netlabel/netlabel_user.c @@ -84,6 +84,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; @@ -103,7 +104,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 43d2431dbda0..44312b3437da 100644 --- a/security/security.c +++ b/security/security.c @@ -2357,16 +2357,17 @@ 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 ilsm = lsm_task_ilsm(current); hlist_for_each_entry(hp, &security_hook_heads.release_secctx, list) - if (ilsm == LSMBLOB_INVALID || ilsm == hp->lsmid->slot) { - hp->hook.release_secctx(secdata, seclen); - return; + if (cp->slot == hp->lsmid->slot) { + hp->hook.release_secctx(cp->context, cp->len); + break; } + + memset(cp, 0, sizeof(*cp)); } EXPORT_SYMBOL(security_release_secctx); From patchwork Tue Sep 27 19:54:04 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 1683524 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=2620:137:e000::1:20; helo=out1.vger.email; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=yahoo.com header.i=@yahoo.com header.a=rsa-sha256 header.s=s2048 header.b=bWPO7pOT; dkim-atps=neutral Received: from out1.vger.email (out1.vger.email [IPv6:2620:137:e000::1:20]) by legolas.ozlabs.org (Postfix) with ESMTP id 4McVzH4TKyz1yqD for ; Wed, 28 Sep 2022 06:07:39 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232897AbiI0UHg (ORCPT ); Tue, 27 Sep 2022 16:07:36 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45016 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232776AbiI0UG4 (ORCPT ); Tue, 27 Sep 2022 16:06:56 -0400 Received: from sonic302-28.consmr.mail.ne1.yahoo.com (sonic302-28.consmr.mail.ne1.yahoo.com [66.163.186.154]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9C7EA1E76AE for ; Tue, 27 Sep 2022 13:06:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1664309161; bh=TLvDtT6OIa/Dqy86qxsWgH+XYsqVXN7WNn96Irn9iZY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject:Reply-To; b=bWPO7pOTPsc3McRLo/gOQVRmaFyGvCwUkzyqQMWn/4RCv8/o0XFJIM6YxE9+qAWtlM0OBcXjQ2n7PIJpIZPaBpTBoKXNIy0y2BUDVY5tuKL7JQD9SailVgR+xc2MXmj8zq4WfIpOaHDnxKlTk9PwqXLsqMI9AWS/YNIj5vHFUcRvs4KgjXZkXlvOtRvxC8WPiu5nzGjJCwneal1kwp4fJOX2308vqDtCyqM121IcXfwdr88zNqvnEAE7SdnyzYOwUO6KGrMlL4lURKHkkJtyEkrQwWVoyw/sv6XjrKGZmivpUwGW98+VpUQ2Y6fD1JQ1woC+Q8xK0aCQFPzGoByNdg== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1664309161; bh=k7XaRGYZ3SJguUGowSs8JHBI1WFmKGptNBduxjWoGcz=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=hLgp/uUQo/n2oC8mG3DaE0W160DkFYgYe3b4K3HFDfsmtGf6riIYttjdEdefm70687ZtbWOKmWXiP6l3me88F/iHKdHU1TldLen9mfPbcikUJcujNk48pIE/Vjr/kznyPQkTjC5HVwkY1UvAtVOCuMpHuUb+WkONXhrUYtRQ/RLzBzqdMaG9M6qyaQg6BsOiYyqIcPbHFgnsA69XsYmeCppU3RevLHlC8v4qq/nBWg7OzGeRrDTkajUsrAKHALhqzrzxvSUxUf3SmJqaKgwhnpP9o7CkItANeUMbMOZy5itNtlePhW5l937yYI+DDa/rLR63umtHR+dGDTrOPqHi8A== X-YMail-OSG: TCXRObMVM1mTjd.V59l4ILbRmQXwPEo1BbIBE3WNqT5EuS36M0XIM322M3X8Ynk DIq_r44zgcMM19wUunCILUuvJylaGYPcajhUCbhhLlMhVTUd.l4699J2.Yhw2MIg_YsyJR22KwWT cZfTtwyLPCsaTBLkSrLzCXiGYoTrO_LqkiXgye30zBstQugRgmi8pf2x5rCfQp_BGL6L3lZn9Mrt y8P8FyGz1qYu4IIGzh4ZGHSV2F6Vnn3Lzxy7tfs0k1agYWGthvQTNAHMTue86j.x1KCQH0Eb2b8j vnNygqkgnAAwNBx4HKWNrNEkA0UD87BzN7RGKumU5fmX.lmVEslsPqXPP_k591BUJKWmyxhldfBR 9ObHo.PreeJceCE9BU0y82RpM7K1ovLW8yqXXTamss5Qypx1FHuP4PdB.IhvF9x2tK9vAgGitP3S deC9e2rkEdx.bVUSJUqmo5Ni9GrsPT9BogSXLLXWmn2Xlnmx73uA4mxhzyhSCa50DC5xLUecb7B5 1b5WGcj4mI988fBpbi4JLaHsTCXebWIoHB.QMQjGmrEO_P0Z8_4ukgA3.AVKjYYWQRw6P8OK.dxk gL9Z2S0isWxhB66pgSIBzduyXxhhIzBwNBOwm_YErgb424GUGrQWZJW1xyBTc9vD.bHhtIV2cBMf RPldB894f4RMFDjpBd91epUxCfLaf_lHE828JbJkK489EeuE3zNHexg_hXrAL5do2r4I1YNy8KCS HAY5JO1SqKdodUML05WXPboCrap7O6P2MkyfrN3Rm5BdghsYphag.YkQbflI2AcjKdRy4.e9hbaF tsMDIDOfXWDagzgKpuHdtCKvJ0gZTXMiKK8HxRpp6Zh4EDwIU7qlQTr0zpNPIf_Tu1JojJ_ExN_r POlgxFMDIlnSiYH.TA6DfDL4cT6tleMg4qJX2GR__VjWYOJfcie2iw4.HQMR7LPDBU24PyyAe_r2 8MjOWGPnJwVqUizYx4lJV9JjUyG5HkJwp9uqaGHvKbi.NfC85mts6YW7X6dvWziDduYnLL_nLIpN v2H6wTsx0MOrhhfDpN6__cf0vQsdsAjEZVUjcE_f7uqeztz4McZ9W.X2mFPLeEfrT0BLfUfBrDuI zIEZceTv0fmbmZqcuYM3Ty.84ux4Xt3EZVv9S.q3Q63MuL7gSTRigyC1ixHqFE8eanlQB1GSupQC XxVdbuOAG_p22LVlL1AKI.Y.6Zsz_f.idf2yr30KHWVhyzgvEnvxJZ8aT5qvrPqL6MiqvEHgNUZe 9gsniAGDlDalneSg05h94g5QPuzWzaLFIX6kW9rXx1uc1_.pcP7EWiAJ1fU9r4A2CRCqOOf.RqmK AYCm3B4HvMyjj6Pmx2Mrs75w0J5BGT7kxb4Tgt_hI4ripKKDipCCOw_KF0SyTswPia8ThJX5C3PN OFEg0wCNdH7c1F2RToPWiy7.8IQiRsMBOSyATwMBRiNonPGlnPqxUKY1bZ8C6Fdbgw9sldcZJ090 ciPaWgOqaX.1tBEcVI5lsMe.xiHdwKeMJXtvwPJvirA_gNDcIeH.xu2dYrZGdvzt.CF7Txa45o91 cC2FTWtSBKM0hvPeqxCrLG465lhGabWyiJiIJjqgFHl_QsPxmU9RGzkix.WdU3e5_Ji8Lgq8NaGu q2f4sJLUwP3OxTD23dFRKKr8uwE2f4CkawDfOdFQ3ALW.uLuZ51gDAnDgPHpN3B0H.FPXLSQSMZn cI1IPruFfOG7esWUvxi4dxiuYFsCBqzK7txbafjlFM8Q6QxMKM912eSB6Y9LZVr593qjYLXENX0A yQNYIVWBVy2GA2rWxYMHIl0Z5u1tDiLJ7_9n23LsNMaK0jAlO1u8yTMZw0KGNcTrPGYTWvbQyogh zDdAWVrDVsVMRlD0gVOu3YsmY05Qu8aO7VVoc_vAuolq22hK8Koq2qZgYFQrqTc0pyAnD4i8rclm OwtMUgvaFGOMCQ7u25AQu3uBEJySZ3TXaGyF3PzV5IhrkQ0ICIbHb0dgLTujHGF0y1Qz78ZiIllg X0W.sUUvg5FypCAB._Sep2gTrsOblGMkaopzP1yqDgolAVa5DT89KjividSBniTaH81NpIW9zGT4 NrkxIezDXfJiOZ4koCCLKNOC53srbt_t16mJ6DLZNslAjedWnYEbaVd2ub7WROyHB0fbKvZQTcVf p6xiDrbAlDfaBO532bwBqdt.RIdrTPwKS9iyOv7zl.6xDRlXDr09U2OLrlIiWooa.YFwEDY5TrZk WHhnB5ZnxDKtUmBYsLXH99gSz.82m0fdPXmwJV33wbjPCCqI3aZ2sKZ4diwvlQ8MtCITf6fKuOth 2lcdLnl.l5Hk3JbxzF88PHA0mC55cUetKv0KfjSr3 X-Sonic-MF: Received: from sonic.gate.mail.ne1.yahoo.com by sonic302.consmr.mail.ne1.yahoo.com with HTTP; Tue, 27 Sep 2022 20:06:01 +0000 Received: by hermes--production-gq1-7dfd88c84d-h7f6x (Yahoo Inc. Hermes SMTP Server) with ESMTPA ID f8e196d1098f8fc47a5a474327d019a8; Tue, 27 Sep 2022 20:05:57 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, paul@paul-moore.com, linux-security-module@vger.kernel.org Cc: casey@schaufler-ca.com, linux-audit@redhat.com, jmorris@namei.org, selinux@vger.kernel.org, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, stephen.smalley.work@gmail.com, linux-kernel@vger.kernel.org, netdev@vger.kernel.org, netfilter-devel@vger.kernel.org Subject: [PATCH v38 22/39] LSM: Use lsmcontext in security_secid_to_secctx Date: Tue, 27 Sep 2022 12:54:04 -0700 Message-Id: <20220927195421.14713-23-casey@schaufler-ca.com> X-Mailer: git-send-email 2.37.3 In-Reply-To: <20220927195421.14713-1-casey@schaufler-ca.com> References: <20220927195421.14713-1-casey@schaufler-ca.com> MIME-Version: 1.0 X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_NONE autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@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. security_secid_to_secctx() will now return the length value if the passed lsmcontext pointer is NULL. Signed-off-by: Casey Schaufler Cc: netdev@vger.kernel.org Cc: linux-audit@redhat.com Cc: netfilter-devel@vger.kernel.org --- drivers/android/binder.c | 26 ++++++--------- include/linux/security.h | 4 +-- include/net/scm.h | 9 ++---- kernel/audit.c | 42 +++++++++++-------------- kernel/auditsc.c | 31 +++++++----------- net/ipv4/ip_sockglue.c | 8 ++--- net/netfilter/nf_conntrack_netlink.c | 18 ++++------- 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 | 29 +++++++++++++++-- 12 files changed, 99 insertions(+), 127 deletions(-) diff --git a/drivers/android/binder.c b/drivers/android/binder.c index 12aa3bea59ee..5cfdaec0f9b5 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -2896,9 +2896,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 = { }; struct list_head sgc_head; struct list_head pf_head; const void __user *user_buffer = (const void __user *) @@ -3174,7 +3172,7 @@ static void binder_transaction(struct binder_proc *proc, size_t added_size; security_cred_getsecid(proc->cred, &blob); - ret = security_secid_to_secctx(&blob, &secctx, &secctx_sz); + ret = security_secid_to_secctx(&blob, &lsmctx); if (ret) { binder_txn_error("%d:%d failed to get security context\n", thread->pid, proc->pid); @@ -3183,7 +3181,7 @@ static void binder_transaction(struct binder_proc *proc, return_error_line = __LINE__; goto err_get_secctx_failed; } - added_size = ALIGN(secctx_sz, sizeof(u64)); + added_size = ALIGN(lsmctx.len, sizeof(u64)); extra_buffers_size += added_size; if (extra_buffers_size < added_size) { binder_txn_error("%d:%d integer overflow of extra_buffers_size\n", @@ -3217,24 +3215,22 @@ static void binder_transaction(struct binder_proc *proc, t->buffer = NULL; goto err_binder_alloc_buf_failed; } - if (secctx) { + if (lsmctx.context) { int err; 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; err = binder_alloc_copy_to_buffer(&target_proc->alloc, t->buffer, buf_offset, - secctx, secctx_sz); + lsmctx.context, lsmctx.len); if (err) { t->security_ctx = 0; WARN_ON(1); } - lsmcontext_init(&scaff, secctx, secctx_sz, 0); - security_release_secctx(&scaff); - secctx = NULL; + security_release_secctx(&lsmctx); } t->buffer->debug_id = t->debug_id; t->buffer->transaction = t; @@ -3278,7 +3274,7 @@ static void binder_transaction(struct binder_proc *proc, off_end_offset = off_start_offset + tr->offsets_size; sg_buf_offset = ALIGN(off_end_offset, sizeof(void *)); sg_buf_end_offset = sg_buf_offset + extra_buffers_size - - ALIGN(secctx_sz, sizeof(u64)); + ALIGN(lsmctx.len, sizeof(u64)); off_min = 0; for (buffer_offset = off_start_offset; buffer_offset < off_end_offset; buffer_offset += sizeof(binder_size_t)) { @@ -3649,10 +3645,8 @@ static void binder_transaction(struct binder_proc *proc, binder_alloc_free_buf(&target_proc->alloc, t->buffer); err_binder_alloc_buf_failed: err_bad_extra_size: - 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 a3c11934620a..bb548f71a824 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -635,7 +635,7 @@ int security_getprocattr(struct task_struct *p, int lsmid, char *name, int security_setprocattr(int lsmid, 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); @@ -1497,7 +1497,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 f273c4d777ec..b77a52f93389 100644 --- a/include/net/scm.h +++ b/include/net/scm.h @@ -94,8 +94,6 @@ static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct sc { struct lsmcontext context; struct lsmblob lb; - char *secdata; - u32 seclen; int err; if (test_bit(SOCK_PASSSEC, &sock->flags)) { @@ -103,12 +101,11 @@ static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct sc * and the infrastructure will know which it is. */ lsmblob_init(&lb, scm->secid); - err = security_secid_to_secctx(&lb, &secdata, &seclen); + err = security_secid_to_secctx(&lb, &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 d14e54098b9c..154fe4c40bb8 100644 --- a/kernel/audit.c +++ b/kernel/audit.c @@ -1212,9 +1212,6 @@ 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 */ err = audit_netlink_ok(skb, msg_type); if (err) @@ -1462,33 +1459,33 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) kfree(new); break; } - case AUDIT_SIGNAL_INFO: - len = 0; + case AUDIT_SIGNAL_INFO: { + struct lsmcontext context = { }; + 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(struct_size(sig_data, ctx, len), GFP_KERNEL); + sig_data = kmalloc(struct_size(sig_data, ctx, context.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, struct_size(sig_data, ctx, len)); + audit_send_reply(skb, seq, AUDIT_SIGNAL_INFO, 0, 0, sig_data, + struct_size(sig_data, ctx, context.len)); kfree(sig_data); break; + } case AUDIT_TTY_GET: { struct audit_tty_status s; unsigned int t; @@ -2171,17 +2168,15 @@ 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_current_getsecid_subj(&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) @@ -2189,9 +2184,8 @@ int audit_log_task_context(struct audit_buffer *ab) 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 8a16ed2f7206..c3d4617d31c7 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -1096,9 +1096,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); @@ -1109,13 +1107,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="); @@ -1375,7 +1372,6 @@ static void audit_log_time(struct audit_context *context, struct audit_buffer ** static void show_special(struct audit_context *context, int *call_panic) { - struct lsmcontext lsmcxt; struct audit_buffer *ab; int i; @@ -1400,17 +1396,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); } } @@ -1570,20 +1564,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 030b8c3ffae0..ec3ef548264d 100644 --- a/net/ipv4/ip_sockglue.c +++ b/net/ipv4/ip_sockglue.c @@ -132,8 +132,7 @@ static void ip_cmsg_recv_security(struct msghdr *msg, struct sk_buff *skb) { struct lsmcontext context; struct lsmblob lb; - char *secdata; - u32 seclen, secid; + u32 secid; int err; err = security_socket_getpeersec_dgram(NULL, skb, &secid); @@ -141,12 +140,11 @@ static void ip_cmsg_recv_security(struct msghdr *msg, struct sk_buff *skb) return; lsmblob_init(&lb, secid); - 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 2bf2673042f4..93855cd7ce4b 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -345,8 +345,7 @@ 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; @@ -354,7 +353,7 @@ static int ctnetlink_dump_secctx(struct sk_buff *skb, const struct nf_conn *ct) * security_secid_to_secctx() will know which security module * to use to create the secctx. */ lsmblob_init(&blob, ct->secmark); - ret = security_secid_to_secctx(&blob, &secctx, &len); + ret = security_secid_to_secctx(&blob, &context); if (ret) return 0; @@ -363,13 +362,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; } @@ -662,15 +660,11 @@ static inline size_t ctnetlink_acct_size(const struct nf_conn *ct) static inline int ctnetlink_secctx_size(const struct nf_conn *ct) { #ifdef CONFIG_NF_CONNTRACK_SECMARK - int len, ret; + int len; struct lsmblob blob; - /* lsmblob_init() puts ct->secmark into all of the secids in blob. - * security_secid_to_secctx() will know which security module - * to use to create the secctx. */ - lsmblob_init(&blob, ct->secmark); - ret = security_secid_to_secctx(&blob, NULL, &len); - if (ret) + len = security_secid_to_secctx(&blob, NULL); + if (len <= 0) return 0; return nla_total_size(0) /* CTA_SECCTX */ diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c index b0f4349ff88f..b5b301f5b3f7 100644 --- a/net/netfilter/nf_conntrack_standalone.c +++ b/net/netfilter/nf_conntrack_standalone.c @@ -176,19 +176,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 1416f8b2fc83..46f49cd2543d 100644 --- a/net/netfilter/nfnetlink_queue.c +++ b/net/netfilter/nfnetlink_queue.c @@ -306,6 +306,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; @@ -317,10 +318,12 @@ static u32 nfqnl_get_sk_secctx(struct sk_buff *skb, char **secdata) * blob. security_secid_to_secctx() will know which security * module to use to create the secctx. */ 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 f62b88c85976..744857eac2f8 100644 --- a/net/netlabel/netlabel_unlabeled.c +++ b/net/netlabel/netlabel_unlabeled.c @@ -375,8 +375,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) && @@ -444,12 +442,9 @@ int netlbl_unlhsh_add(struct net *net, * security_secid_to_secctx() will know which security module * to use to create the secctx. */ 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); @@ -482,8 +477,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); @@ -509,11 +502,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); @@ -552,8 +543,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); @@ -578,10 +567,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); @@ -1104,8 +1092,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, @@ -1165,15 +1151,13 @@ static int netlbl_unlabel_staticlist_gen(u32 cmd, * security_secid_to_secctx() will know which security module * to use to create the secctx. */ 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 ef139d8ae7cd..951ba0639d20 100644 --- a/net/netlabel/netlabel_user.c +++ b/net/netlabel/netlabel_user.c @@ -85,8 +85,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) @@ -102,9 +100,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 44312b3437da..cae35e5767ec 100644 --- a/security/security.c +++ b/security/security.c @@ -2321,18 +2321,41 @@ int security_ismaclabel(const char *name) } EXPORT_SYMBOL(security_ismaclabel); -int security_secid_to_secctx(struct lsmblob *blob, char **secdata, u32 *seclen) +/** + * security_secid_to_secctx - convert secid to secctx + * @blob: set of secids + * @cp: lsm context into which result is put + * + * Translate secid information into a secctx string. + * Return a negative value on error. + * If cp is NULL return the length of the string. + * Otherwise, return 0. + */ +int security_secid_to_secctx(struct lsmblob *blob, struct lsmcontext *cp) { struct security_hook_list *hp; int ilsm = lsm_task_ilsm(current); + if (cp) + 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 (ilsm == LSMBLOB_INVALID || ilsm == hp->lsmid->slot) + if (ilsm == LSMBLOB_INVALID || ilsm == hp->lsmid->slot) { + if (!cp) { + int len; + int rc; + rc = hp->hook.secid_to_secctx( + blob->secid[hp->lsmid->slot], + NULL, &len); + return rc ? rc : len; + } + cp->slot = hp->lsmid->slot; return hp->hook.secid_to_secctx( blob->secid[hp->lsmid->slot], - secdata, seclen); + &cp->context, &cp->len); + } } return LSM_RET_DEFAULT(secid_to_secctx); From patchwork Tue Sep 27 19:54:07 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 1683525 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=2620:137:e000::1:20; helo=out1.vger.email; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=yahoo.com header.i=@yahoo.com header.a=rsa-sha256 header.s=s2048 header.b=PsHaHrRb; dkim-atps=neutral Received: from out1.vger.email (out1.vger.email [IPv6:2620:137:e000::1:20]) by legolas.ozlabs.org (Postfix) with ESMTP id 4McW0r4Bqdz1yqD for ; Wed, 28 Sep 2022 06:09:00 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232399AbiI0UI5 (ORCPT ); Tue, 27 Sep 2022 16:08:57 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44626 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232923AbiI0UIg (ORCPT ); Tue, 27 Sep 2022 16:08:36 -0400 Received: from sonic302-28.consmr.mail.ne1.yahoo.com (sonic302-28.consmr.mail.ne1.yahoo.com [66.163.186.154]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0942A1EAD64 for ; Tue, 27 Sep 2022 13:07:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1664309256; bh=o4oVFCboZkMzjMN/Ordi3YRBDO22EzTXnNOZCFcA8EQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject:Reply-To; b=PsHaHrRbES+qU2uKRyVMmbfTRYkaYnSdC0WVDbPrK4f/uid7f9GjIVyt1W1StZu/AN0Q0ixDIRsnUW41dxRDVwEg/yZqvtYwBNeySu+SX+9bWorV2yZeOtAJsQfKMRBI9gqhWVMc5tCOTIrONgZZgWSKrlAuaL5hDSHaMhkNKCd4PpxoS57ouCcz+51tgRzWhisWy+yek0g1P8fDsN2aBh2soNPCmkOa4ouNX6XthfyxQ7WciuwFjBDkyrgmaGYOvosi6qR88mzZT3Ub28cnrNyh4yzmP6jfN5ZCZBS+dlNrMY2l/qabb52vw2n3Jx7krwxbcCnupZ6kkFIYOCL8hg== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1664309256; bh=BNTUEcWg4aCj5tjF3FxT1PS/ColI80EIA5vTdWKPBmc=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=ssqqfHRfGomrM3IXfp97WJUUvLN/Xu+KcA+wL+ik023Ze8yh7WDE3AlM0hHg9bSvmok6/4UH01/wGpgm9jJoxnI6mnW89ufjdyE018S3fZNPaHawyko9AoQMGjaqWBooyzBTiaJz2o35DAwrehUusdJYm+f5in8nbzI0nnsswaOeE2U4Q+1xnPmmsXPZYtyrHfJeQGlhmvLoL5XFb7OTyiE3ePmVLB2+6UlRDsqqkZspRPXir9uvjOcIPhVYcou3hGzRdAJxfc0oEe5xQdzEU2ArEi0BbPqiQiq87YAZMFgmdB8ZXlguB6hkdQ+SaHsjPb7Hvxxv28CxMIyST4xtuw== X-YMail-OSG: loejHKkVM1lq6BmsoMQUN_Geugpq8O7nnYJxgqGKyeyqRJd0FTQ7t8TU7t98Ei_ pHAcZ.Rd0OxmvAlI.8PoYLwXAyvT5jjH00GNHi1y4d16Qm0tKbwP8blVbOzYXlhtww0A5.cmSDa0 moW_IV7kDFgvcnWJZDdskGsmAajVg73F83rUWlscOuj4OuzaqE1uijozq7TaiesanBZcQOCAs_hB uV6mdFyRljOzReUjNerdIwpa0Wt2p3O8naHu.f.PdfsZgfzB.k4XtINt3j29xL9TjmGeHsz9KbyM RMFhoE3Z_EroDCtFixpY_lcVlNd6Z44lA1rpPcoDYGyvz845.NpAOYyYEzrCN.7V41TEaaQwCPyX KHp_kM5iKH5.bskyhhFGq3OZbOGawp81T1LQ3bvjHnrLfT5tA1mP81HE.ZOGFzagackuBo2KseTH po.IHG9RnQjzkM0uPCa_0EMwJ04_pLZLkJUvKuWVpCVIsJxrc75zhd_o0KTBpWMm_aCamNG8trzt Rzy0FBjsVq5F_q9Mj2EYLaWgdsZsZozz_lpgYz0ChaGvm83XpPy1OvaIB42JaTSGDC8YYv_FcHyx kVoN59s7amBH4iI.MgqLcTpjVRwVrhIyD03DquhwAJZKZio9yaSbWeAIFL3j3dCOSN0hdU6PX_0y iGT9J_hfsf4LQfUcmn9ECwx7CLgU.TvorfyhJzIsr8QebnOiS4ArabC_Bya.8ZhuXGSch.7CJNi7 kjgZxzUMpdl6QWedXyRrzhNoc2j8MGgFTMNWZN50_11Q_Fwr2cQqvJy7CHG7MChf4qBsQ3fKGkP7 U5tbWD2WFLD8pG.mzerFQIi9Y55J4rwBBEVSmQ5AdYurpEAUles1pdMp7CMgJlu5egTLWLzXqcIt 7_nv8xStVw1.E5pSTG_y0hZOGszS_g1IyDazNq86WLXn2XVVVnXbzzaf3KUvC0HTJgrbuZxfnybS 2ncfaU3.lFVZ7nXQU0kp58Jy7pTU6k3MHRnoxhw5soRBLVMN4Tjkg8Ytj1jCe.du3UECaa0DF9d3 wi0uqA8SvnUj1JfQAm.OK8UwUP0uvf7RR_aZjP2VdRGESGoBSHeia0d4m0dLqoBRP1Z_iNotml0_ tiIBpd_QvnPcZjMT_MmQIpQ5Hl4L0Lzd_6WqRM4LDQcXaw9AsFvx5o4UJoB_xMQA.1stk1IF1uqH LZ4pzYCwUrAX36annizoQrkWmDZ7JZoLrj8qnCuJ17nLYVLiakm3M1grkXlJf9Arq56Er68J.kJD qLD8pXBC109L73mnhr_7NGhUUztT2KXCsOXrBRxsNFdkwgPwIE2AANreGtwCgwkjHV0WKAzfigAp AEYxKSiy4auvTrtPz4Lu_GviU_K3S8L5.4BWycbT95Ofk8jVZzLjeuENr8ByCrpfYMnrGrWK6IJk wp_ZY4FMYwAmgIrtey0GwjrxH4oTqaH01WXJz4AZvP4trJ2h83ybx6UiHOJiOhkPNUjFK.r4U.Ei WDIn39TjZpZeMJ6moAtGZIT9EwHsgdk_nH9PV1N7TVFW20A7uR8AJnPAmWhltFzm94bzygJ8K9hk S9AJi4J5ymlVSGIi0Cdg.LGWyzd3_CQCiBlxMfe22ElOMvDHmdPQ.y.878tBdx8cILw79BwQ5Rp5 IFCwiBuG3k8w57l52CdlMhMlGHm8wrkV5ylnKASw1nxYKu2ZFznwLuFLNBa6twMwo6.cuRZcj.FJ zwYvhpNCCmdLJRXY18oGmwyuwAfn8anrEc9P4e0c80AKiFvdg_MG6lPv71RT9Hzf7mlWxehB0xhI 77q61cnnzI8GSGnVqy7HsIRL7DoQt6Up.ZB9LxQJwUkeZ2t4rjisgYgVgF9CMp.B699C81TG8.Ke 8OYvYTsx4JG.pIFuOCMo8b9VTkUxDtpyLyonP_rhCoOPfK355jTbsLZxE9J4lh6QBknccH178s0l X27fz5dLg_53uSS31s5W.qjWCe_Uuev9ZBpqd50LU3yRluJ.6PMwsE_SJHBgVT3ffvZUdlaPF3pL 0_DQikPSS6jHGFMkMybu_5AySVL6TAdegmvCx2Nil174UI1F5stnqziQ6w65YAUtwFHA5OUa6Br8 kdeprrRheWbKj0C0gkmxzk0Bfhzs.MyXBAxsxcUu7FveQ0GalQafE3LKw96.XD14SPfquL3V.bNL K46DOULYmsDmDiTMN0bdAuWpYcFe89aMsfTSkV_Ahj6hfdtOnMf7AXK22D7alsVCMh8sSF8.FIRm zUGtXVvKFDlZudBcrRUrcKegkiZQvnJpVilx4AJ12mvknmnfi_wcne7fdTMEfy18FtWHI1zCxqLQ itz.EFAZC8yM- X-Sonic-MF: Received: from sonic.gate.mail.ne1.yahoo.com by sonic302.consmr.mail.ne1.yahoo.com with HTTP; Tue, 27 Sep 2022 20:07:36 +0000 Received: by hermes--production-gq1-7dfd88c84d-mgq76 (Yahoo Inc. Hermes SMTP Server) with ESMTPA ID 3a50061892aa4d3f76ff4b42bdd2ab9e; Tue, 27 Sep 2022 20:07:33 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, paul@paul-moore.com, linux-security-module@vger.kernel.org Cc: casey@schaufler-ca.com, linux-audit@redhat.com, jmorris@namei.org, selinux@vger.kernel.org, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, stephen.smalley.work@gmail.com, linux-kernel@vger.kernel.org, Pablo Neira Ayuso , netdev@vger.kernel.org, netfilter-devel@vger.kernel.org Subject: [PATCH v38 25/39] LSM: security_secid_to_secctx in netlink netfilter Date: Tue, 27 Sep 2022 12:54:07 -0700 Message-Id: <20220927195421.14713-26-casey@schaufler-ca.com> X-Mailer: git-send-email 2.37.3 In-Reply-To: <20220927195421.14713-1-casey@schaufler-ca.com> References: <20220927195421.14713-1-casey@schaufler-ca.com> MIME-Version: 1.0 X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_NONE autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org Change netlink netfilter interfaces to use lsmcontext pointers, and remove scaffolding. Reviewed-by: Kees Cook Reviewed-by: John Johansen Acked-by: Paul Moore Acked-by: Stephen Smalley Acked-by: Pablo Neira Ayuso Signed-off-by: Casey Schaufler Cc: netdev@vger.kernel.org Cc: netfilter-devel@vger.kernel.org --- net/netfilter/nfnetlink_queue.c | 37 +++++++++++++-------------------- 1 file changed, 14 insertions(+), 23 deletions(-) diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c index 46f49cd2543d..3a7d1a693c5e 100644 --- a/net/netfilter/nfnetlink_queue.c +++ b/net/netfilter/nfnetlink_queue.c @@ -301,15 +301,13 @@ 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 void 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; + return; read_lock_bh(&skb->sk->sk_callback_lock); @@ -318,14 +316,12 @@ static u32 nfqnl_get_sk_secctx(struct sk_buff *skb, char **secdata) * blob. security_secid_to_secctx() will know which security * module to use to create the secctx. */ 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; #endif - return seclen; + return; } static u32 nfqnl_get_bridge_size(struct nf_queue_entry *entry) @@ -397,12 +393,10 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue, struct net_device *indev; struct net_device *outdev; struct nf_conn *ct = NULL; + struct lsmcontext context = { }; enum ip_conntrack_info ctinfo = 0; const struct nfnl_ct_hook *nfnl_ct; bool csum_verify; - struct lsmcontext scaff; /* scaffolding */ - char *secdata = NULL; - u32 seclen = 0; ktime_t tstamp; size = nlmsg_total_size(sizeof(struct nfgenmsg)) @@ -473,9 +467,9 @@ 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); - if (seclen) - size += nla_total_size(seclen); + nfqnl_get_sk_secctx(entskb, &context); + if (context.len) + size += nla_total_size(context.len); } skb = alloc_skb(size, GFP_ATOMIC); @@ -610,7 +604,8 @@ 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 (context.len && + 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) @@ -638,10 +633,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 (context.len) + security_release_secctx(&context); return skb; nla_put_failure: @@ -649,10 +642,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 (context.len) + security_release_secctx(&context); return NULL; }