From patchwork Thu Apr 7 21:22:09 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 1614653 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.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=oSMFN1NX; dkim-atps=neutral Authentication-Results: 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=) Received: from out1.vger.email (out1.vger.email [IPv6:2620:137:e000::1:20]) by bilbo.ozlabs.org (Postfix) with ESMTP id 4KZDvx0dGxz9sGP for ; Fri, 8 Apr 2022 07:26:21 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231545AbiDGV2R (ORCPT ); Thu, 7 Apr 2022 17:28:17 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38520 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231454AbiDGV2N (ORCPT ); Thu, 7 Apr 2022 17:28:13 -0400 Received: from sonic305-28.consmr.mail.ne1.yahoo.com (sonic305-28.consmr.mail.ne1.yahoo.com [66.163.185.154]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DCF8A19B050 for ; Thu, 7 Apr 2022 14:26:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1649366770; bh=KzbFwwhuwjYfTBU4tfTxK1dAwBTSVWuzxkwCQg5qsUw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject:Reply-To; b=oSMFN1NXgj5nT4hKPSc4GG+4fnWK1CZ5bjUbH8NTGAm2xjEvWr+dyqPBM8nnflIDINXN6kldvhV2L6KESnmzDIKZ+brRuUkxAz5eRGoew5pSKjHRQuGYiOK9V9nSDgnezN1ln+oMlR40e3vdM70FVRvHbM+aZgxhXOdnmNuyY3ScIgiclZJf1PlpzVHOMAbwNcaLDeNVzJw2rI56tblV2b9KExw8NSmlQeFLJRQzLR7U3I0d3gp5W2IXbRTVIf55ZhLATcW72j4vJ7Lq4LWHE4C0rkl6cxNzV50aGh4u8dY8Q3Ed97vHQ44tP9jdE1+7eOgZV0E6yy4HY5sUbs2nsw== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1649366770; bh=xDz3OU9PDS8Hz3vIt1H+suPQtNOH14jBaooUb2W5sc8=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=kLrtIzaVzKmcpaXa6VckGZznZoYy7j7+KWT1RGKrgmsE1nodjlQcYCrizD2SwhIZDe4AtA03VLPDUxewf14n1+wayQgGn95bRNNAtnPivYtvGQVQdZQDhSIAKr+rQWWqXowLXCFltKw59+wd6qVims93HSqne5yNGo/0uCaDxpl59TMeHq68y2zhu/YiqL9nNhkvnz90hQwq5IRLNJUU5O9derX04otTJhfzqIyxp6ZnfskKJMdT5RwaqNht+cFj8wh7cat5JNrbywsZ/ZoObW0B+ZWyCyFb4h8BKvglGBwZn2thmIUuLi86GBWgbtOPvkNWyQSMPaw9d/NAN3ywiw== X-YMail-OSG: MzyUCcgVM1ltKIjPm6j7qa.8FIaE6f6l9wXggunUKktQq5N72GVK1ey1w1qZZbc xg9pb.0AgGm2ZmHNKflOpl6ZyT7YG_Lv3YoC14bNlfWUas03qKKM2yk4aSHnUjjZbv4yO8gbho3K rikpppNY51LNf_XTBbLcUIO.tdXBxPmC.4TicHa6YNbf3HpnZQAVAJ2PyUWRTcTg077MLbulL5_Q mYjDuEItFlOWudyI_EWutNBXzXT5Y4RL8kWgirywC7.38_zUNnu_VHH9FMG2SbdX6oM1AW7r4K8A Sst7dlSSI2NhttzYzlb0qMvUyYJt_oSS_deIFDs1kGTUTnnZ4CDEx4lg6mugQqU801z5gz3qp.tl TU7cXj4B5gcZT2kIpvXGnUvrFDCekX6ua8u_BSVLRbLSAFXfPgZ9PGqkda4En3pxLtwBzMXkQjCC DYsmsH1.by7_dVtXlJfxzYagZPLmIUf7T5KKFSpV.FEdSNGItRbLT2PMfoEJmgDCR.5cY1PSEJVe 4mTf5PRtYHGJ95abB_86el.9L5zsjZ1LQ_KW.fOUud84UobC6bwPaPfrC9mJuZ51_gk3ZlrGK7_h EnkvsQQxNd4.ebaiI7jZjQB..l8yBhOGh1Sm3AI0gOrCJFfW_11tC5vACVmn5j8qNxVCPHkXPqjK xHX6HiGvT4WUYhPHHnZyhkWujjMXnhXaK8yqqC_qhG_iFZGk7t3PY7LMN9oITyx9iEsQkKq4EZx2 QmCfoKhk.cb2yiqLbuCCwssu7dTSZMlBzBesIZPlEvLPRiGtvdO8N1oTKB1BJwME9ufVL3fYWmvS mBFoyUBbsIstgI9KhIUAFnTwx5VlJapGi79vO7RL0nrKULsAEk224O8wkTRl0WYQhJzlUcKV1ggh 6rdJ1Rrjomsz.jMgmDN4JipHcdCrUVkXVyqfT1_P8syoxhk6UwVolEwdM741Z7SVtosR1b5Xadk5 flkfMTlOs7D1OoEENmJDD_u2.kIbSumkVyNAhR3Uxjvfulp12eQV1CK1Zuaerrjjs9qsj14X7rar nPT7EcR.AZn9eCIzY2xbeErQFryYTyjYR53qfhovE9THT9m.VNCpAPrna6UZgD8924nheQbpbEPk iaXqmYmp7scZ49Nh2n3Ucon3b71O8tojVZ9Qwm_s0ZceyK.aw8A6qiTan__N1C8iJ6YetyXp9irU r20ihzZAHE6UI6arba0q.PINjAezaoD2vA2W.1sQZOkMtX6qJAlUKVBV5xbtphfvQV9uQtVgUjgb JwGgZCy4x736XzDB1Uit.RmXgbBChy0tfPkbAQNzSJGYyE.CCQTYz2lxHthzhelwHppBZvGByDrM W2ETLeMBmAhgDPJ5v4H9RgS6PsN1UE9qx6XDdatO6zN0mc0kTfQIdMts6hFORf0mJoXZJh6QHPXc LzLurR4AbLAaqzY9rkUl9iVHvlwwsxFZJEXBGLQa7.dfQ.6L72qwuEvOVRNKYhMh2xRZlSqIUWbB OcuwWSChxeb92yIjhcwNblydWxgZ3_bQcm4aXMXKDapayZ.RBYfE9Ssxpt42KpzONeSF9hd73jmJ DQkOCHVOFLWJDOvuy0DfKIXpa9zvPd8fBiG9mFOWrCYQvpjsXWZZwwNw5NOkS0DJf17pYt5Bal6q .yfLXPwWqMdiOOj7XDh6QpEArmGvkg2Y_eLf2MKqebD_FZewxIpjkwVJXvWu0i1PgyX74vePzQXG S06FhHovs00kiUG3RvVQ1ZNnbOhpGfIXNjSZlzYsRSkMpr7Vz441Vi2N9kZDQ9hmLCSy8Dil.NmT g1qjvrsq08RSARU51K1dfANh5BN9fyvFUWhLpxdoU_iTCZTWqCsKssV.2PP2uUi99iZz0OHzRDKc 3u26ZrFEiJIxBVftFpWQVtF5P.3V1nxYDFXaTxyl8oMj7bON2YEnwhNMqG7bqiaKtZK4xMQnY0cH 5eX7dYbpEA6lC8XCXOXofZzNqOj8G6aXDhLXv6XWXHxw1Kycl1qGISQBa8ipcMJezK6SVaL6JNuo 2fvZAI.KmW4z11OabV3UlHFMkON3TJ0uaQmerAuqp6jRf6vbRs7AGOFHViK1Fmwe19Jd1hkUJWqh trsndhZigYiDLrg4YZNqlfrxMJzODSkOJATUp0f3pQBTJjEKEtuTtNe0nL802lsxi.djUXWG17mW DhNIfqzzuRmxy2ewK0m_DxdxiKgYMFRyGqy5GWCwUtJhFPz2UAG8BREffj9aI2c7UVV2CNATtHD1 4E1d4lr8.saw36tQUImulFcEVULXS_Z0KG.gSlkti9rE3iqVKLEleDorvkhmqoAcxCI5kbf8OhrQ 9wyU- X-Sonic-MF: Received: from sonic.gate.mail.ne1.yahoo.com by sonic305.consmr.mail.ne1.yahoo.com with HTTP; Thu, 7 Apr 2022 21:26:10 +0000 Received: by hermes--canary-production-bf1-665cdb9985-zm65g (VZM Hermes SMTP Server) with ESMTPA ID 1b8a787888cf9c0809abffd2a20a44f0; Thu, 07 Apr 2022 21:26:04 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, jmorris@namei.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org Cc: casey@schaufler-ca.com, linux-audit@redhat.com, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, paul@paul-moore.com, stephen.smalley.work@gmail.com, linux-kernel@vger.kernel.org, netdev@vger.kernel.org, netfilter-devel@vger.kernel.org Subject: [PATCH v34 08/29] LSM: Use lsmblob in security_secctx_to_secid Date: Thu, 7 Apr 2022 14:22:09 -0700 Message-Id: <20220407212230.12893-9-casey@schaufler-ca.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220407212230.12893-1-casey@schaufler-ca.com> References: <20220407212230.12893-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, T_SCC_BODY_TEXT_LINE autolearn=ham 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 e9f185e9162a..310edbdaa14f 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -199,6 +199,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); @@ -529,7 +550,8 @@ int security_setprocattr(const char *lsm, const char *name, void *value, int security_netlink_send(struct sock *sk, struct sk_buff *skb); int security_ismaclabel(const char *name); int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen); -int security_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid); +int security_secctx_to_secid(const char *secdata, u32 seclen, + struct lsmblob *blob); void security_release_secctx(char *secdata, u32 seclen); void security_inode_invalidate_secctx(struct inode *inode); int security_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen); @@ -1384,7 +1406,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 ac4859241e17..fc0028c9e33d 100644 --- a/net/netfilter/nft_meta.c +++ b/net/netfilter/nft_meta.c @@ -860,21 +860,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 8490e46359ae..f3e2cde76919 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 e9f1487af0e5..f814a41c5d9f 100644 --- a/security/security.c +++ b/security/security.c @@ -2211,10 +2211,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); @@ -2365,10 +2377,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 Thu Apr 7 21:22:10 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 1614654 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.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=qpXOEzkH; dkim-atps=neutral Authentication-Results: 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=) Received: from out1.vger.email (out1.vger.email [IPv6:2620:137:e000::1:20]) by bilbo.ozlabs.org (Postfix) with ESMTP id 4KZDxc30LCz9sGP for ; Fri, 8 Apr 2022 07:27:48 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231420AbiDGV3p (ORCPT ); Thu, 7 Apr 2022 17:29:45 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43468 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231445AbiDGV3o (ORCPT ); Thu, 7 Apr 2022 17:29:44 -0400 Received: from sonic305-28.consmr.mail.ne1.yahoo.com (sonic305-28.consmr.mail.ne1.yahoo.com [66.163.185.154]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id F17681A3AD0 for ; Thu, 7 Apr 2022 14:27:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1649366860; bh=3VJ6drxV7v8cy0e3EmrY0f1OiWSC5vBe0nWMsh9nu5A=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject:Reply-To; b=qpXOEzkHMgEE6c3bH6jb+lQu6ND5onv01MSx3B2LIdSMyqqOIpLsJiNDsBpQBu5jUfv2fTQySH+mF+UgvbWlr6QfCjclouScWAEw6l+nHwrXpZIL1iCmHd3a64z2ez/uLLibYUDddhSjuD/gtem2vC5eNOxMxHtzXQ6TRhSCWnuKq1RwMzQ1EJ0WwIusScrzueXB8MZZ4p4O00Ikf0/naAAi45PUULyX1VpjvFtG/I7s+cWBnl8JuzlOoOW2f5blszd/hBZvAlvOZ24lhwC2o3F7S7r/PTsLkm3m4PBySjw0Q5/t5jPzFwQIvaIIVUMZrBbwNKoDtjRyN5orxBiUkg== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1649366860; bh=BaOIKqSf+1q5UJbEt4lQYsxthtqDDJsRuNdAlhWOptp=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=iWlN7K2pXqjlDzeSbyLwnKyd/lx7vSnTmbB1MI3YCwAeWBCc4dXLP9M549mK7NZfB1VbgrDkvn1irrr9a5Vpd15FozGtwsmRwDFFGK2rb5/EOZDcwfOmcx1Fo5AN58NPcKNe+21LMHzLUMP0xn1p1pRpkchhSBeNqB7R8O55Ou16krz2nrTBzdlGBUWnAyk6uWZWEEue6mIorBm0SR6wzuVMp4rr8WyyLNqrKP1L8pybhK1/S9kkjJPU6ZC/ADhR9Tjo8wowqVJGWk2cuSJQ1bXs6/t+6nz3GDQIXdQyXVr8WMnmI43Lo8wSCGnJTG1KOJfs9ZDOJ0tn/rGYbI1a5Q== X-YMail-OSG: WGQh0FcVM1lG0jD4.Z0ocrRCnjRAVymi0Y2CVOodOjVp_i.Sbw1lyw38dE8xwt0 Vmcxv6eDJcrAmxkcVFrFHWhN_6uc_YMkadJ9hkV.Zatcj3xLLDt1XWkLM0N7Tcsx5rjR0HsqNKG_ XL0MG6GBGFVYJXxvQ9KRs3iUYton_JiFmIt9n2UAPE85AVmXQOB8XP3x.KPBMbpfw5z3_9KFU4M0 yjsHZefOUyVMtZ6FDtdBxwCcWrGnQPYg9HFqBQSIE01ZE4y9KipyffvgzQfuNtizZ31BhdxAIhni 4NJ.R5ly_Qy5wipdZnn3WEm_uq3NCh35EvefGO.d0oacvdy45ZV.nPGTvRdMaNVOdncRDSM2gYrD y8FSyFSJzfr0vla95JjmtDy8jD2jE12.sPiF.WE.oAfNAGI5GtIHC3HAtv3KsAt6_DK109q9p.Am vdoTcykg5BkI.WdP99oEVFVqlgiOSNC.fhJ50VyawgWXB8RL8UmT.nGvesKD8K6iuNKraIpvV0i0 sXHY0zH0MPABlNIXWEDuc1yDGAmcdSdQC4x16XswwvVEP90UTSZnXblVrI9wsIiG_HRrS95JgOEY rjtQDj7gTbRwLackUfhRGisHXYr5CjCmh3KpXh.kGEL0qJwtrYCl1xiHntrRxNaJdZyLKGWIAuaf DoreM.i6PiCMoL6K4GNtwU1qPVnhS7Y_tO5rqzHECX4QHK31FlgNwQ6ZZOoP6xsUCeIUdq3zbxbm vzvTrjLRuxmY3OdJm2DfpzdzkUnotzxbnAB_ESIvOZpkBVrxRWmPAC8.ymYX2JwhkK18Xlq7R.sh HdPbTEb.UtT8h3KACOqXxZoM8AHlzJf1hC6BPMA6S8UbNo_mjQtO_7iOYtzYm9NJYay83rjY.hsr qQx0V7jhqCGYyH58W7lXzVBem.xVwlUx5tIwH6lsN4DV52yEN9G9uEmVoyeTKehDzfAr100qrWwE yuTZE7mDeFgFZLznsbfQzh.VsDAYv7YiXJ9l3xz7sFvAALHfVQqG7R4HlTPiaZKjVB03HYKMrhXo _hBtbB783wW_ooaoVOvpNgN3dVtzllyqvhbyIMNnlXbpOGvnvh_80TictIvidEve4tGLjvT_Gh9c y16pR1dnnPNqawjkO9AdOMbBO6lJ31RyMBCm0iY9EJnOlH0fn8am_4ljfI0vq5uidcTVsls2_ZYh 4vC23ahrg83oXGmDwfTQMakZua3hDJM53H7Ftj04Uv..VKAEXfdDv68Tx3MQszPxHl7Sbu14h.yS FehPqxcZ7.r4uLLeVUncwL1F9P9eX6gi9.BToEPykNL.dKL4vwHUhPVdIDCWl4shMR2CMvYXW7NK rNUL7VOc9zm97wSDzWUNmPwlq4_R0rTUZfD9WHnlCoqXhNwBUi3sowDKnCOfPkuB8xiu9gch3erz RMMyBam_qRGdXsJF11iglCo6gEb_z9bo3iEgCN2KLp.B_8lhG57pWuUzncXqweno.RzGlZk.GEY5 4Aks_upW.PJYQaBQzSf3a51dqwBz4HS_PhLIIYsmpIYD.SbFr9J0aAArryBBOQIhYh.dPtqW3mSN xl9xmMc8tUcv1prPg_2rLxlZxcYnOIvr77xHTQfQ_C48PrPz1cY321H62eSYpA_8uiSODR00KRlj iMdPGFgtctNQrDZ8.tG01f2HC3KHaMQEvL72TOezwVToaQTW.1vU7WVoN74e9N7LibO6rVBOgdnw lFwNReWJGOEV4DPQCyiBirm9CHyKJJMxGOwWGnuggyBb33qFWSWgDudwpZhF8Vmb1Kn32s1uTbNB d5KodFkIg6lfKAHzuO8DseZM2UfZUmMaPbi_UgfvC6a3tDqqGdENpyd3JCfRm6hDAZNlZWdGpXUx vXu.Q3uy64oa7kvzyTdTZpPZdx6dCrE9oCTwaB_okBcmryzc3w3hdV_lrQLnIDDVUZ4Kqu9uJ7Ef OQ8ljEBZq6gbPN6XJJ85dnmwjXYb7oSlYbS_wcQ.oI94eHmQ0Jg00IFFkapfNKw5PTmhn3KHrYoa gdwlaARn6IBPKo9GrqI5QVLK.QI_SmpjiaHPL28ZwooXNSQQ2gBkxns4veFI1UwgN9ihgJ28enp7 Wx6MPtwK74JIbGcJ34ep6VXk1jxR357DIcrXxZm4MI.KiN5l4Sodv_k345EV4lMxPeBBNzYfChmk ygFRjWEX_fWdY8tbtxC6pqsR8BbLm1wjliZLUkKSikU99m26NHXKOGuYo.0CcyXzDRJZcG0HvsfQ 7oA0aO.TYTzFJ6yW2b.4j56akbKqxA._Y2py9jXnStrNH8KgJnph6vOICagDmJybcPZZUjGqJXm0 Gug-- X-Sonic-MF: Received: from sonic.gate.mail.ne1.yahoo.com by sonic305.consmr.mail.ne1.yahoo.com with HTTP; Thu, 7 Apr 2022 21:27:40 +0000 Received: by kubenode522.mail-prod1.omega.ne1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID cdeff4c1363a36af98b9100857bab95c; Thu, 07 Apr 2022 21:27:38 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, jmorris@namei.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org Cc: casey@schaufler-ca.com, linux-audit@redhat.com, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, paul@paul-moore.com, stephen.smalley.work@gmail.com, linux-kernel@vger.kernel.org, netdev@vger.kernel.org, netfilter-devel@vger.kernel.org Subject: [PATCH v34 09/29] LSM: Use lsmblob in security_secid_to_secctx Date: Thu, 7 Apr 2022 14:22:10 -0700 Message-Id: <20220407212230.12893-10-casey@schaufler-ca.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220407212230.12893-1-casey@schaufler-ca.com> References: <20220407212230.12893-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, T_SCC_BODY_TEXT_LINE autolearn=ham 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 8351c5638880..381a4fddd4a5 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -2981,10 +2981,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) { return_error = BR_FAILED_REPLY; return_error_param = ret; diff --git a/include/linux/security.h b/include/linux/security.h index 310edbdaa14f..4f940ef06e51 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -549,7 +549,7 @@ int security_setprocattr(const char *lsm, const char *name, void *value, size_t size); int security_netlink_send(struct sock *sk, struct sk_buff *skb); int security_ismaclabel(const char *name); -int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen); +int security_secid_to_secctx(struct lsmblob *blob, char **secdata, u32 *seclen); int security_secctx_to_secid(const char *secdata, u32 seclen, struct lsmblob *blob); void security_release_secctx(char *secdata, u32 seclen); @@ -1399,7 +1399,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 7690c29d4ee4..2acf95cf9895 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 a9d5bfa37cb3..10b9dc253555 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, @@ -1118,6 +1132,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) @@ -1127,7 +1142,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 { @@ -1418,8 +1434,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 { @@ -1585,9 +1603,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 445a9ecaefa1..933a8f94f93a 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 1ea2ad732d57..a28e275981d4 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 3e1afd10a9b6..bba3a66f5636 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 a364f8e5e698..6269fe122345 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 f3e2cde76919..0a99663e6edb 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 f814a41c5d9f..6e6e44213d80 100644 --- a/security/security.c +++ b/security/security.c @@ -2192,17 +2192,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 Thu Apr 7 21:22:16 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 1614655 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.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=l9gyPK8F; dkim-atps=neutral Authentication-Results: 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=) Received: from out1.vger.email (out1.vger.email [IPv6:2620:137:e000::1:20]) by bilbo.ozlabs.org (Postfix) with ESMTP id 4KZF1M4MlSz9sFy for ; Fri, 8 Apr 2022 07:31:03 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231593AbiDGVdA (ORCPT ); Thu, 7 Apr 2022 17:33:00 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55854 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231495AbiDGVc6 (ORCPT ); Thu, 7 Apr 2022 17:32:58 -0400 Received: from sonic311-30.consmr.mail.ne1.yahoo.com (sonic311-30.consmr.mail.ne1.yahoo.com [66.163.188.211]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C97731A5D75 for ; Thu, 7 Apr 2022 14:30:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1649367054; bh=w40bsvxz1maTfxCP5OPrFydafSqo7FsPfYgUwwtQr5s=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject:Reply-To; b=l9gyPK8FzolcWzaM+AAaSCluyFWhXXvjx90RIBJ9UPdhX+lbYLoL0Bk0VdcVO8Of2YQcgkpoEDoLd4WmfeTA9jQCQ5+5Sp/TE7AekdLKQFrRzLYY6FptIrEvq/ukbs64jczsNabRjWXi+3PK5zTukuK0jWW00ZFhxxMYVYl/T4IGlDzb1Nd1xZK3XRNpDqEfU7d0DvRUoCs+ciwblbpVt+h0b4R0tgxzGkKi6OVYZVesZswiZ2eXww4oCNOK0Ws4ovU+1MQj+SMZf9NlrpC9M3PkZbNsHsP8c0MNNhQBEq8Y6sIjRohXjKsnT+l39EDkminFYq7MFAe1X3A4Qb7hQg== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1649367054; bh=BmAupHtE6MCpIZ0XgmX1SzcB+r3A9L5lJj6gjfvgs1/=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=AvBtWtKMOEhfg7gg/z1vh/wd9anBrqcyN1EyQdLEoiXRGc0HkDXlvBjpKtBeVU8NLpWrs0ulh8SgMkwOIxnd48u4dQA1fqTfjOaF3pZtYttHqHMsqGz3hDBrzV/2bD41KrgsOx5+ejbDnMLHdU4QJvVQM6UTpCDrZOl6aLXHexKvDhDYdme/7MEjclq7ru4lXr9a73JMm75HJdgtqXV72o6kVveyS65VVyapfcwYz4oGPu8av1T09MLg5LMVqXVEtZVFhfzSFluajdPFmIpk6EOJDUQDAfKdmBW6eBmpWV495KysSZSpYZCMe2Pu8AOBZj73Fk+S07kZeYx78UxPKA== X-YMail-OSG: G7Hhjl0VM1n90CjZkEr5mkNBS.sGNjKvudF0jyNJCUWJjPVSy7fGrpqxiXr6ahN 6VYiHI2yjjDPZrZ5wOQlUtfxOsBX6q6rYGlHHkfG7M9lBnni_KJGBWZ1zNoqilx9INLt6ez_pIGh bH7Ng2quZCPXMS9.lxxCBIAxIQsEgb8WZTmOI14f8boca5qe1sO5khoGK7p5unYNvC.DU_HCWKQs FyV3KjJxYEMINjSrVhyjlhXNRnG5avCTbNYKJZgXuQszrD4BcesLxn80yS8eEBbR3sxq1tPe5D.v pIWKXmEo9fOc_NJAokyEaM6OpktktMZAE9C06Qpnz8ikWvLkH245tql7Ssje54m7c3uFqaQS69td HI.k.39EcFSBi1tyxci2kGI_utFkeNQ36XpSpPFlHs_xsZhh113x_VkWpm8R1Y_F.DWQ6feGPFjy 2bSdPLezwGi5kpvQ6vY.EMERKt56dFZK4xzngo3RanTjokf6bJGI9SsVHSOSzah4MfdRPVqyg9a3 9732bqJa0nxAUr.dUUfiiFj6ieIdYpEpV3HHre_iXr_6_V3.tw9f7FIFFSwXCxBZpT3MMTG7qWeA _6MXmAacVs1Tr3SBi5.2gYirsH8hZMK1zuS2bwgsZcwLNmZrRdSgCRN_gMLwEwc0CxeRPqbMLnIU I.vgO6NalJvdCOuc88eSG24HJDVK0VG6TulpSTGzWlcou0qb8vbIfpo3WbO1Lco1jzx6NsrBU6nF BxFdj1aBsgg1wR6VoBNA59eZ.2vLtAgnTBkdMTt7M4Wqlm0ezvsGd33YX5AYpN8wcSLRU_726frK Rdzx6xLTuUmfDOqrgJfMRZDO9qjZM6S8qMfjfnFOP6IZ26FI6wNd_nSC2ZeeTsbGvfkJXpWJT9.6 fkD1bGZxnTOHe65xTMBcdXwLaVn8SMOz05bQahbQEa4JbzlwhYXzcur3lv9JXYiAvYSoLQsWIUVW yVbUTHDVoToLCE86wGi2JX0c7_vjrkQTZpaipzgg9blGM7AAAK_JVJ30fw8Znh2a2nn0N_HnF.bt MnxhdHhk.XXZFxRyXUGLb3sn95Yc18jr5KM777SpxZzkMhMomgOKUuDqgFOVGN1F6zC17WwpNaOv TKJxAQInhqJXOZ6d6ZuAkX95QZko_Mlh4.kctakg41Z8fIDgFhyYAN8sdgfwVLmw3tGVOc_OHq_1 XuxTw8OEij3S9DH_LQw4XjKAjtSuw7u3QglPpbvT8jGMmD7W1Q6E_qPYbAcbRzsE63uRPFccLfA1 e82iYwyRFYT5m3dCPoUjavHhWV6GnY_dPGzQuwDGtLALcIJaL8nJD70psY6W5O_eXLrojS4QQuw_ 2Big4WKUNw6hReLeFP025t9AL7ch_P66XtVML9E2aNdkloAvo1nO0D8AYmd5dSfM0_msD2VOy9bx YQuNU3tFv5zVVLNh_jj03p6wzx2Ak9w97uHi2ArIO4cF2xHLIuUHsDHgtdTu.GKDUGz4nk7uBOsU Jw2j4wZhI2XrNlGw003t_wJ1xrQnJ1VYK4XyS_5J7Etusgfg0E9LwI_RWegkBTt3kCcHPIIaY0bJ vFZQ9hhCm866CrGh7LPfY4pbT8DFhc9Qzp5Yf0nvbx91uaBGtlqCU7Mordnr1S9sEUWZ7OJxobcP 7Ct590b2ywioFmtt7BXafJBXb1acWLJ04twwo2uWQrNRq4jmVIxSKdTmGrBbAq59n15g9NVPGwFJ YCpeeFNbsq_r.yAh6y5n88SX7gwpGdyNzMR2kbr_lvZ9QifXyzLtl_moPRKVY85PuPFHtLut2F4F XZQS2Y7AxqYi8LonBvG.yWQop899mewzIz5eYGttfqqXD8VCW7.R5cZsSI.fDr.TgeIrk4nhVxzB 7d_vt7erHRGze9c1g.yBTpXxnbVPpU9sZdmWXXA.m1iA_d7Rimi8aFwRDzzFAd.C3B2TUGytrgkZ YRGVCBlD81qvXiNtxpUmR4BLgYprbA4KOhGh6OnzBbIiuvbnWi9vvWzjjRhXq.LCqix2Ky.4IZEk 0CWqgQGoIXEX0U3K7rxQ0H4xf0bQCAgF8XMtmv8vKP.wpDq9rE5QsTe6AQbyUeehhL7L1ARquCq2 n3h4z63iAqNZhdoN1uzPqwgFOpN3fFghviZ3o0.u9d94zXs45_t1K30vHin4guJMLBPN8pT2flQ7 jA_AbNBZB6o7Zq5e98tC.Zk9YA.wd_zghrXRXngk4hm9RYgpeaiyTgnRPrm5c2F74Jvsb0.Sugjn x2uP6pdbNQl4Vq4v5_Y3y2YIX.P2Eb3zkMroIZJqdnOdsh3TjjHW51eO8HnxuVOI7NnR9nX8mK8U HXo2aDCzaYYyO_lpmwfcSlj0eLAeKTlc5YPp6W4vMzNSTNYMkGdFVnN84 X-Sonic-MF: Received: from sonic.gate.mail.ne1.yahoo.com by sonic311.consmr.mail.ne1.yahoo.com with HTTP; Thu, 7 Apr 2022 21:30:54 +0000 Received: by kubenode532.mail-prod1.omega.ne1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID c3ff6cebaa6b68d3aee0bdab632d6ae4; Thu, 07 Apr 2022 21:30:51 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, jmorris@namei.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org Cc: casey@schaufler-ca.com, linux-audit@redhat.com, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, paul@paul-moore.com, 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 v34 15/29] LSM: Ensure the correct LSM context releaser Date: Thu, 7 Apr 2022 14:22:16 -0700 Message-Id: <20220407212230.12893-16-casey@schaufler-ca.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220407212230.12893-1-casey@schaufler-ca.com> References: <20220407212230.12893-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,RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_NONE, T_SCC_BODY_TEXT_LINE 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 26838061defb..2125b4b795da 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -2725,6 +2725,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 *) @@ -3033,7 +3034,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; @@ -3433,8 +3435,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 afec84088471..8ac30a5c05ef 100644 --- a/fs/ceph/xattr.c +++ b/fs/ceph/xattr.c @@ -1383,12 +1383,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 e3f5b380cefe..9d84e592e7d3 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 da92e7d2ab6a..77388b5ece56 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -2830,6 +2830,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 @@ -3341,8 +3342,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 4a4abda5d06d..ce63621c45af 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -135,6 +135,37 @@ enum lockdown_reason { extern const char *const lockdown_reasons[LOCKDOWN_CONFIDENTIALITY_MAX+1]; +/* + * 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 * @@ -569,7 +600,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); @@ -1432,7 +1463,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 2b670ac129be..0eff57959b4e 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 2b27ef99f0f6..2202952c830d 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -1121,6 +1121,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; @@ -1138,7 +1139,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="); @@ -1398,6 +1400,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; @@ -1432,7 +1435,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) { @@ -1594,6 +1598,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)) { @@ -1602,7 +1607,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 933a8f94f93a..70ca4510ea35 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 a28e275981d4..f053d7544355 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 bba3a66f5636..3b6ba86783f6 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 6269fe122345..f69d5e997da2 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 c86df6ead742..a8e9ee202245 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 52d3d0601636..0cdd12c4c157 100644 --- a/security/security.c +++ b/security/security.c @@ -2379,16 +2379,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 Thu Apr 7 21:22:17 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 1614656 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.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=MtWunMzz; dkim-atps=neutral Authentication-Results: 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=) Received: from out1.vger.email (out1.vger.email [IPv6:2620:137:e000::1:20]) by bilbo.ozlabs.org (Postfix) with ESMTP id 4KZF1M75TTz9sGG for ; Fri, 8 Apr 2022 07:31:03 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231487AbiDGVdB (ORCPT ); Thu, 7 Apr 2022 17:33:01 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55910 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231527AbiDGVc7 (ORCPT ); Thu, 7 Apr 2022 17:32:59 -0400 Received: from sonic305-28.consmr.mail.ne1.yahoo.com (sonic305-28.consmr.mail.ne1.yahoo.com [66.163.185.154]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4C1B914A6F9 for ; Thu, 7 Apr 2022 14:30:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1649367055; bh=9tuF5SxNkWWTGOrRIuV6AzZ33ET1GEIP9udDQ6mZJ1E=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject:Reply-To; b=MtWunMzzvzNETmVGYFeIJpBFd8VlYJDlR1agSs4bXEETA4G1x2c4MkdBswgOBUi6icvtYGLcD7vzJ05rYI+z3WleLq5RjMGUOY5FAbx5bfQSoN6GGN1yBkgGyzZvX8aMTbQD6rWyCXtNhMdM/UnQ0ZZj8gyOtGV9aX9gAHpX8DnQWJpf/3fhKsZmG2MG0/JVsC0L6jME8lEuxgdPSBuEnokp8/7opzqsm2J9dzhH/gwiKdLxFpNEgIESlxQ42VYOVcwEX6C1e2N4bm/BYUzHZuf2V7/V080802/5HrMcaSoeGUae/4IXIu98DTb/aigYsRZAXKpVPIy14J4rHEegAw== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1649367055; bh=RDTuYob8HPROcI3ZWmZRR5LIt5Nf7oK3WSmlQKrNtq5=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=eIdf2Vc9sDRs1TqnH4pdpRbx9XY5TB4vYeS0w5+WfA+fh/FcTzrpfLZIMIjGOAKH+LEV/FqPo6POJYY9RLEh3hlLB6hk/2+93cXBZ2h0cBGJCELnHxAbHAEJlN+6aAUs2l3BCOi6wQ3H47MS2rqagznBZ5HWkv77BHZYh5hvfpdet7L+HWenOiGmDDfNqiyU/S9nlyGTcvD0xORqEjXvve7XUXnA0cT6ugfK3aWJvAXFrtKmsUuIvmNOUAgeLopajVdWSGBiHqXQvCrS5LzQ0/AwodOsoawQtVWRALvMvliFsaYP8YjCfiMeAjD3maILOHKcusyx/yaC6kcFZ4xVtA== X-YMail-OSG: iadUWYwVM1lOVkUuVZk5SwWcW8Q4gEavuAQrUZ7w.FDf.peJJ7Cmai65vn6m_Qa l62kQr4T6HsSddSi8nN6CaAlql9GKYQIz8RtVmWwaJa77Z0F0vlDrQcMvxPKT2hvOvoWfCN.ntPs CqDAhEfuLE0yNVU3W0e0T2BW0kDMJ8GGpnFMAfXVCh2vvv25MEc5rQ76xMQ.XHfUWszqFZkAPxYj 4iSJ_CtEo2FwbOcoGezleX9XBAju4Y5YTlfZMkpv4XkyAZ14H74wimrtasLHNoRzawB1lgPERYIs .HTzvP4W8bWfS0_Phqc8Uge0ZtNVVQsGuRUW.i5H8uPx9vayxmfSLn1OF4_vkNJPFrvEL8gvjO1m S0GY57tRq0xflPzOi0ZtKWy9in3BKZTPKf3CpRKx39Bn9gAFRhLb.obxWe5.kGjQCVEBixOPZWu5 s2PrRMJy5IJquvC7NTyPscx1cpMKgtevosotU2ZKBAE_N.kdyQeDf8tAiBVObduUEwXy2a9hxrjh crBv_nOExhNcjJJIaMg3kSAzA5GhP_DsohF.lcI36vrT8IYpYjXi_bNMmf.kG5Lu0mQuk3COt3Y2 WoWMVaBxgf0VC1R000_9mRrQo4F1u1aQH2wKBWjK8AEuuvJiAQz9KhaHZIxmz5Sp5FbRIQ2HyXNz vFg4tiwmYpP1RM1qUPvMUvYLi3XrKto8CmgkyHRFOOl0EkHjXlYO16bCTG0r0M5cQXQpRbxlb38c jPWbVgzdTzmOEsqt8q3hibHCx9vMT9ftwoC8vvGDEFIObJ29P4pXDIMXMK8Z1saLNYR6_r_Pctnf hMQZtuvoATYK_LfmZbxrcZ1VKRlPnf4GsFnF6ZlOZWDYfGl5LdpeTygD89ebaji5K20N7M0Kqnhp S5UrbTZg4jgMrcZhrZLFvlj0ISaOfKUdhdSxXwXNCZY6ddoG3pgdCTfsyP3hAcKndfLu9sZMXfEI 7QBbqsx7vdO0VKDPAqcEC4Ocimkl9wfAxRaUPYmGmU_aoPNLW7K3f0wl3wtZ8ysbfgNU9DXbYbKQ 0TPBn62sS6uD00suFepVLJelzQnApULvo_c2zvJ2EBJA8A86bj4mQnZP_fgyLhqUPEwmZULLnbnr QLMkBlHzBLLZx9vSiyWdc9gsZSAU3IJuDgoNwutjT8IV_3Ofuse68a_QMGp141RvzOJgmH715XC. .8KRMPgnO7hC.Pj6OsXSjbjHhl8dBs5O5R7xrzEJr6A4c4eP2mqOSJK.xgHPiqm3lHQJD6HyZwyH VMFT4WNuZNaS3iSuTgJRP_FD.ZZwAFoSbuEQmO_M6Wl7x5vGU1n7rp4FrWGBeJIMZ4a9U9O7696z BEdwuVPBFxHz5.oQAsFmZI0Ec8yoiNgpBYEERxhe01ekSae4KfWa.Z4sg.1yARme6EouxDYGqQHY tA4KRShw1maSNk4qVYQUls6hO8nX.qW1gyp7SBWNy61L6zmoHWXAYVcMB48IpIBq833._Kw4rIJX nBbFm2YPY5KSmJT0liZUw874hg83bHmdVpP4JVEIy4l8OFzcEUxSqwNfp.KquzTI_Uo9b8gVuhmb RZFQBUFpaqOcUs2Fa3cdaINhQzGSBvaJxAMkfXTFG1Z8bi_uaKxKgMJO7cyg5kCHIt9M..yDxmvg kkZd.hI35uxSaMKaCGDM1JzrBDg6a3.2Jr3Y9JoayIIkm.fYbN_NsojOaglQt38V28X.kUNcrcVx B4.T8irLZr5mVCIsya1msS79AO5SsHelaF0_LUr09LEYJSTmeoISJNwFKTmU3eduoxOZUZfc8_fo oHsqEwITivWyVyDcmd8rAXwixn2lWHZUmZozjti22uNL_IFfkhrf83qfHj._kwQL0BDOa6G34VR4 NMxXAG2FB3s_UCLToO7y1J9QGYX2_xI.sbsXkamDp8UWMQGnS77RVeis9N__0e8dPVUiY2nIp_Vt TC71dZmqqhmLkDrM_CqEN5BNuS0UtontkND9IMXaKdXOjm9F2M0Peq09j26i.t4PKjZi3mYwaULa xfRjKPQpsSaZtjhCNg9SJkEMhjDNuUQaBUKgNjJCucgC0NCRM_CGxNXUc5JIZE.wZAKHHgGSufZ0 FA1w2Aq.qtz5DMUcVi1QXnUdg3A8zf0W4.6X0.6dfzSv45OG8pSMkYF5kWcqjUMhyPiM5B0uFlNd R3IK7wt2OjKZh9ZCckczkyBH7zipddwUSN4kAO4GLznQ0Wi7sNFLMOkxKWMvGk8AMlWiMGYBmySv j7.rEkGDlIPevCL5bUAIcn6WFtZuXA3r65yKhxtuhieDFFDJwJgRwa7D4G6tyErjulli3Sk2uTEG PVuiO X-Sonic-MF: Received: from sonic.gate.mail.ne1.yahoo.com by sonic305.consmr.mail.ne1.yahoo.com with HTTP; Thu, 7 Apr 2022 21:30:55 +0000 Received: by kubenode532.mail-prod1.omega.ne1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID c3ff6cebaa6b68d3aee0bdab632d6ae4; Thu, 07 Apr 2022 21:30:53 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, jmorris@namei.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org Cc: casey@schaufler-ca.com, linux-audit@redhat.com, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, paul@paul-moore.com, stephen.smalley.work@gmail.com, linux-kernel@vger.kernel.org, netdev@vger.kernel.org, netfilter-devel@vger.kernel.org Subject: [PATCH v34 16/29] LSM: Use lsmcontext in security_secid_to_secctx Date: Thu, 7 Apr 2022 14:22:17 -0700 Message-Id: <20220407212230.12893-17-casey@schaufler-ca.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220407212230.12893-1-casey@schaufler-ca.com> References: <20220407212230.12893-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, T_SCC_BODY_TEXT_LINE 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 2125b4b795da..b0b0c132a247 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -2723,9 +2723,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 *) @@ -2985,14 +2983,14 @@ 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) { return_error = BR_FAILED_REPLY; return_error_param = ret; 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) { /* integer overflow of extra_buffers_size */ @@ -3019,24 +3017,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; @@ -3080,7 +3076,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)) { @@ -3435,10 +3431,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 ce63621c45af..9a6a53f7d8d8 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -597,7 +597,7 @@ int security_setprocattr(const char *lsm, const char *name, void *value, size_t size); int security_netlink_send(struct sock *sk, struct sk_buff *skb); int security_ismaclabel(const char *name); -int security_secid_to_secctx(struct lsmblob *blob, char **secdata, u32 *seclen); +int security_secid_to_secctx(struct lsmblob *blob, struct lsmcontext *cp); int security_secctx_to_secid(const char *secdata, u32 seclen, struct lsmblob *blob); void security_release_secctx(struct lsmcontext *cp); @@ -1451,7 +1451,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 0eff57959b4e..a885ebdbb91e 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 2202952c830d..a5d01fcdff3a 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -1121,9 +1121,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); @@ -1134,13 +1132,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="); @@ -1400,7 +1397,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; @@ -1425,17 +1421,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); } } @@ -1595,20 +1589,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 70ca4510ea35..ad5be7707bca 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 f053d7544355..07660c7dd342 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 3b6ba86783f6..36338660df3c 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 f69d5e997da2..35c3cde6bacd 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 a8e9ee202245..46706889a6f7 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 0cdd12c4c157..50bdb6cd61f6 100644 --- a/security/security.c +++ b/security/security.c @@ -2343,18 +2343,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 Thu Apr 7 21:22:19 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 1614657 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.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=AygrJMe9; dkim-atps=neutral Authentication-Results: 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=) Received: from out1.vger.email (out1.vger.email [IPv6:2620:137:e000::1:20]) by bilbo.ozlabs.org (Postfix) with ESMTP id 4KZF3H1rNbz9sFy for ; Fri, 8 Apr 2022 07:32:43 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231608AbiDGVej (ORCPT ); Thu, 7 Apr 2022 17:34:39 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33726 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231490AbiDGVei (ORCPT ); Thu, 7 Apr 2022 17:34:38 -0400 Received: from sonic311-30.consmr.mail.ne1.yahoo.com (sonic311-30.consmr.mail.ne1.yahoo.com [66.163.188.211]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E9E353D4A1 for ; Thu, 7 Apr 2022 14:32:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1649367154; bh=V+vPgvaKFDTnMpIdljAHcVYg6xkRL77vK84TmLoWvrc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject:Reply-To; b=AygrJMe94ON0a2fPsjkXbF+cTMAD1wBOW4wg7IybNATJ1ldbE8ThV8UM3ACdYU/ImlaXUZ5OaK40gxn4uJp4Khq+Lj8/gr0CB9hJItAfcDRZgFeZL5lWmPdLQ6Gw6yQXpiHsAemYmvR9sJ1AP2pfQT5wvN2XQLkSJA+aLSpZuL2OkJ95UuAehjSzgUzH65LqxgzsTObEUJTrXIrDTkxgwEKZ91Dq9o+RBZOOkLf3dWIBrEdKiKTJEPUW0Dm14tFZlqE3Y+fa8TruM6EF+eCBjbqz/5yTrhi63DQH3LTgT/z3jAGVszLXWAhSZWxNeN9TImzH5mB9LSFWMpPhvTzj/Q== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1649367154; bh=IthVljW/O3+ym3xan+CiQyL/TxseU3zfVxmutmdIVLy=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=adqtxX4UPGAyejJcAMV039mCZOx0vhGJtg85h0gz+bwLrQTaZRyIwVwviNqE3pv8visGk/uJiejaqkhSV1LFYW75+V+khqETBS5b1Fm/gcKtIovcJfUh9q9pPRCsf/tf1oYRifOGBE2DaspzGFg09zcCe4vrTIIHoVbYaOA5Tt1nsamQCG6aq1RF7K5PtVdcxaNgkk3CzSL7bt+7Mg4UYB9wEvnpbUIq5pg6P4HnC2bBcdLAa/72vyZrKzKWhlwr/TePj++yENZ7OuSqBSZTZawuRBYOp0ok6InFgkTVqCFP4EzWesxYHe9LLj98iw7SolYxfBue6kAYpH4KhgVuJA== X-YMail-OSG: yax_31YVM1mm5qahMKHiRaExyFbkPZnxhLs1FuvaueA7bZQ1VLQi4VstymHrB4a eMnH4oYl0l9Ae6uHY0__fMeD8oztv5kmBQLYUy7AgUBoCEMuIhdEjQZPOCMAs9so.E15jQzn3Q20 qtLU0ylQgdpyocFGJ.UUBQsvxuDDN33Gvum3qYV.6Jm6qP5d01FcjQLmsyL2Cox.4XpVpcblOTRs TPiHBR42APa6jk3o6QxKf4EN760kJZLTISfPkUgziTPFhGyASx0PS.1Iqu61nTbprItEC91jMrjp Mzu.wSMMIfkiFm23.OMg4hwWEKk4QtjbmSQZnsft5ahPnTgcPnRkIEEt9wR4I70MMqJighIB_NXy 7aLOylnCO4GDXnwT1PUTCIbMgx8EPinR7ytUXM.9JBOjflyTHP3KTozXFtXiUO9QliF_wGjphlg5 WyvOJyB_hMeHAMYZHGkDluPPBRaO2TPQDyXwoSYr0bxF9EtAsndN9KCnpvqLGjMSJTXZrEIJ5NU9 nLwENg_R2q29DrchuJBs4rT6eiJCdyLxjegdyC8vlp4hlP_9nuJq.nyAXhxvrMuKXUs_G7HcYKN2 5iDUy.lmwqZxXeTtdDW.UJzKndSeL10bUtBQuv7pwlMs2U5zeAB8UitHF71g7EBg9JQ._NUWMRJY zKjrmnTeBeMz_RplPKn9BAvZRnKo4Zkp8DHD_VUjDCNFicxZWhGZPsNyZgPhM_EfKTyCKrpxZBGf _6Ccvz4.VTnLswmBmL1V..FshiM7nbFYMm_fQcL6pWO_TrTrMyF7OS5V1e4joUQjdc_78P6I8b3r 6G60eHYuAXEamwEuFTrBVQPuygdeqFdo.rKO0SjUGJauiP6RMKj6BHzoGUaFrZ7KzW2VIaywDQHF zOm5rXBYJ1GNEzJdUKfgmFa9kAt_B1KmGUsx7i2nrtQFEbTUgBJV_QZZf3dRMdvupZeNs2rJrZwT vGmgFiubl5BMonz6nwkwUJUvepaGr1uUVqh3MwWwz_lFaU5l1cDOg0UnN3uj97tsd_JJEMxeQCaW 6jJ68Sd47pCQHu_.ziF8KdAnA5bQLnmqTTNJPGWYlfjaTgW3n7T5QA1vLjVUKihxZxaPrNwjZJ8A iJRwZaW5DCUIXbvmzpuwxW5S1w3CUacvZ8mmF7w1_gjqwltVVP2LbVG8b69eg5.bUMZ7aYm0d3y1 5cWfS83GSpmAGPPqxhUxUx8IGg78jDUpJo3fztSR9CH_6.VaHhCqJEnvXvtsaM7f8BCOSvKlzfV0 ULh2rD85dRY4PQn0ahGGooYu1jc6MD19RBpNvyigGCQ.H897pfgi2wjz2VsyRy.v3hoHNp5O0.cY wNzjbQPaBm27erCMTt4Posk1NcekQudqw6esy4FqvHMRPws1vX66CWHXHmTLnCG.qIN4Xu.rpOQ9 svioUZucJc15RvtNKW7BRRgE77J_7bRlf6rHZdb_RenlLjZljhZ4CD3VWhGkzqHxKr9cWAeM94cv huzMbWEPtS38luavPXpFfDaLSJZZxn._bXO3vn_kNo2VPxuy0ymaAVO8EHLWs5XXTRYQVqmHGiRr CWvo04DWOrfMRfc2I4niyxt0g5MG4OgOrccMgtlUql9vduBdLb6J5KEsve0mXrx5GQ05hzDaOQqQ uzj4R6aQzBzEN9Z94JhC1mRMNeYb6uPUcQ2jOD7Dphi.Dbu_PBr..udDkCvG2r764d_RKlZFvz4C TgAgbINzUS2KAtKX6ma5_F6wtFthvbZddeWuBJAIo4V_Cheri2SK5yCOqtWGvz18uhoRwrBhy2AU wAmDa5LhpQ99VLm2w7OMIdLd3MwPdIoaFPYmtJwHzdIEKfZ7oMRy8gmPNEkdZFquN_YHLNuFje5p dMAlbLMi9O08649Sd91J4tbHqICLyUapg3bfPOPGyUYjFMItONU2IcRvxQ3RN_PXwBRvDtoydVd. 6JZAtpIBKhkahJX8rDCnvsupoFQUX6HdrIHW6c1oB8g5E2gATI.mp.8RvGQhgIT2Qx3Qmdk2HzIM GdyMNRkmm20HVEOgkb6ebsPFxGKGNWWqJHTgzjSfif2UgWjZ3m0_6cjBrzhZyrJa.sR3SLvfVZkb dHz9zppWqNu3vjcAiuBoWvp83HL30EmHbwW5ZT5IztSzjd5T6F8QRszLJYQHhyApjQP3rRMfvlTB ajfzkotMozkk8wnlGko17xBhz_1HdMAJPoZJNMV2s8U7HM3snKIQ_kzj8pGcKz7k5ZcEfoBDkNTe QGsDViaTJA1kw3auPR5JnxO4LRloHwhtfIuuEujHDQ7Xs0ebD6XjikRkovSWo.YANPT_vvKa5zye MeQ-- X-Sonic-MF: Received: from sonic.gate.mail.ne1.yahoo.com by sonic311.consmr.mail.ne1.yahoo.com with HTTP; Thu, 7 Apr 2022 21:32:34 +0000 Received: by kubenode527.mail-prod1.omega.gq1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID 1c3e27710c5567bf7ba0bbb257134c66; Thu, 07 Apr 2022 21:32:29 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, jmorris@namei.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org Cc: casey@schaufler-ca.com, linux-audit@redhat.com, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, paul@paul-moore.com, stephen.smalley.work@gmail.com, linux-kernel@vger.kernel.org, Pablo Neira Ayuso , netdev@vger.kernel.org, netfilter-devel@vger.kernel.org Subject: [PATCH v34 18/29] LSM: security_secid_to_secctx in netlink netfilter Date: Thu, 7 Apr 2022 14:22:19 -0700 Message-Id: <20220407212230.12893-19-casey@schaufler-ca.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220407212230.12893-1-casey@schaufler-ca.com> References: <20220407212230.12893-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,RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_NONE, T_SCC_BODY_TEXT_LINE 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 35c3cde6bacd..f60a0b6240ff 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; }