From patchwork Fri Apr 15 21:17:40 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 1617929 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=hSiJfrWF; 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 4Kg8SS2XLQz9sGt for ; Sat, 16 Apr 2022 07:23:04 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1354419AbiDOVZ0 (ORCPT ); Fri, 15 Apr 2022 17:25:26 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45484 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1354616AbiDOVY2 (ORCPT ); Fri, 15 Apr 2022 17:24:28 -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 78AB1D557E for ; Fri, 15 Apr 2022 14:21:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1650057699; bh=KzbFwwhuwjYfTBU4tfTxK1dAwBTSVWuzxkwCQg5qsUw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject:Reply-To; b=hSiJfrWFbHdl9LZfihf5S2AllUB5Qm7fOY1kkQw686UfN/qntdyQrepvqmGKxfWCIN48ZY0Q7fhoaEGNua5S/VCYrf/yuS/tiHmuVhnQFmqNHuaSigeXZQkg6Fj/vM9pekjYisjJ7rcTqbKmbBZ8x+dBxhLsj/w+2e/fay6ovP8/3YCOLie3e+aXz+QHZsd+yYWtUpALrTYkzFOBb17O2SkCoBRTdK8j8cLgHUbE0d7Z8SEjt+TrslbFxnxrk+6cX9cpdVOXlKvB4sUUam5Lo46L3H+xf+FzalsyKVATuJ6sQ/0THk1cx9hHFl9OnrEhZrpUm2syTEthdIxt4xiOTA== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1650057699; bh=mVf3QpWqgRjD+PbmoMDGV6gWcwVi0wKV73OxI+rp4Ox=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=ioclYtID+oEIQ1WYd555hBg30Ic/x/tEz0mXXR6HgcVtZmIV8/2jqHIyczOYa3eg0m/gCMIN5pdiXiUxaymT9Zf+TwQU75rooAouB9PbSQtyDlmXLlj7QqAl237HdMyyKot1OsTviCk8csmqhczb8J2Y8+Rwr3+8Rf9leYJrL7KutFGTDEyLr7TGi+hBdQnbiI5pAmDpbX7ZJZeWu2vfoffqzSymVr3oeD1VBbPHC0sEgCA6BwMSjzWWjwGiqCijov1a+MEDdSP2D/nPtm208D7Osr+dbdrC5tZDBYmUqzQDjkpkqeUPc9teXzU+SUh/2+k8buqxNauKjJhSqZlmzw== X-YMail-OSG: aIXsmEEVM1k05ipWROgmw4DdM0fAIMtlMj_x9XSOp030ZAqEqSen.2SOgMrPgQB r0aSqB8QU._hWWYecQD09iOwjYmJ1CU9iPhPNUxIBurTXYyeBSvCD0M_ouTt7vDFWO1.n17amyD7 Gq08iqe1xYujmhj277uCwHseSiDPSc3NOYdPxEa1s4puyc_6WZk5PmspZbY3ZT7nxcRPgzP0e7pa 4hK7SCgvfDzRUCp6iJuQ1zzyu8e5Vv9ev7rhJzzgON9E5FSESQEOaHrlgvWeKL3XqmREX77bzyi0 zoisxBMrz18yzAIzfuRBPvYz_TMNWKl4X15rJTDeH8Mj3gDeVvcNi1lDme0ciuCAGdyx1BZUb2tQ Jax5aFmXnQwWzkrOSw706LPJfZID7MU0zLtx_OY.0Sy0wBstvBKJ3NXHeQ6I4_07rbaEqDS_yKMF _gYml.8vFvhTu5BpBIgJ1s80FF508BVkWVH_CxkgfjYfu3SOXXeIvXzbQI6RgjVSLD35visIBuAV zO528D5xZYr_6P5RZUwoOJfNJTKeU8BSibYdhTIdNpSBQ7d2OVFyZyPUatqpKksJ3DUrpRKkozsl RpFCU0AyZgQz0NtQKBPgMFZhYAOWgulFzWxSaOsvF2NcqaYYrqUpAjFxzjgOqssa9NSezDwS.zF8 BpscLvKDdzFgDV47CiN07l0RoIm7yOPq__7JWSqVQmFPzupt.z7NRH02zDGz.AcejofU3bQmmZVq iUG11J8KOWqgDmSPptSohaON.6MpRtBkyrfVyDqPuNAuOA4mmDRghaRNI5zxjK7JyI33dTpukSjx _jogT.Ii4LAn4pKr3ZpiHvvGcgmX0n5AHwMQdgtKALuLnr.gOtu72mRmVmNBtTI1oN140XbQgYhy dQ3aa_9H_z7BsmjhPRse1bEIgtSvDBY4OCMe2POoz4D93J79ChOAW8VIrM4vdCLjoGuSjn.FmgqK iQvu5GZBFdmHVSZGUa32BT9p51Ekko34EFdsCdDapkog71Ee6zFOemuajxMGSF6.lphG_jdp180K Q85gQ4AxQ0xy7f9nZ6wAW0kOzb7NCixOCiQbXk.X9k1N33EOTDkhFpMoL.9wuqHJ6i8GtfKqwnVk 3PFUcx6qhXqfFeNG2btIIcLNt_HdFMVe532.7aa3wknNOlT0_StWSglZuPa1FwhRORyopHrxxwYE WdO1GKtsA80PmYkt86xqO3njYb2EFx80T6.alDbrWs52UaPEpZw2EqbqdiuLI_GPlIs97sRkFQzb z9HyTM9dI0hwK4mxRlrkeac0iOknFEpMzkFo.oZCSBTKJpFbHdacGtxr3KpniL3mg8fOwOLK6hpf jRHtVi37zDRYEdtbsHYaIbLA_tZ3iEX.J3FIPspl8hbjPHUErH6f.VbZdJmLJ2uRrji02D7jdn8i BfwoFf.PFRTRa9v6W3hEP7VkmX1H8cskpTS8M7m8MhDViezKmOJaGpzhMWVPxgB806VeZ3mNnvZc ZxcmeroSfIlyo9s8_Z5JZ0kPwAVhp0Hbzq8GgAi70iVoG272orvqBQh1fOByQ18WX31YzvqZCoYX APKavoxzzMQwvZizcNJVAwaPyN9wW8ejcbbvv.bXQrnpXu5V51KQb8XlYzYG9YvBMnGF.mlxRKF4 Irz.kMZ.9IRNJcV0C1yB_q9vg2QlkQ61TKAarS2T49o7oab.iCohUkQ164WF6gcrwFLyreV4eAYe FxAOvEr5YuDg6xRDk9GsyPRr3A96vg_yzk1ArpUYWcZnlaQ2pA9MTXv.bsnZ9XUB5ySC647ftUjS dAJWAzw8640SsyYCwTjylLznPtjYWKlzuX4v_y8RBB28CBN3LxUd7PwhLZ5ojU6vwH0Vt3teXZkp .Xf5nXEiDpsFdbsYMjrNRZXimvS2ZLb7SQ5R8o2jb9ktOXQxUv3HWQZFN326xMQlzA2GSBqmnBfC JGNAQs7t.j7t7lbj5rxPJekRDIl_fKDe9XkkeehF13bQvc1caVvWH3BS9x0hhRHffbtyjehL.WZ6 5qf4ZQgKW_PQPOS9AGqz98nTlaw.6OMWfrBg6jqT0vtlAnb0tA81XU5Atd7Sg7vvREn3FQC4qqT3 t6LVqdMfmO8ldI.xP51qLFYDwk6voR8OIqNv3wKEvI1WRNwKhMJtzaB0Rw6HZVGrLRtAlDxRVBvD bOhgwJMAU5d6DKMD1Gk4YTFBlgJqnnyt5r3HTvnvX57zLBFP7r7RKkQWXgGizDJuAbIrFUlyNuiK CO2CDuz9h.70YHcafYkPS1UR.lpBt7l.6GwL.wYcLARh3AuB.xBnr2cLyd3pwVJAW1EJRoA9Pcaw XjdRcl1P7WN.4h.GxEhbcTcEx9HLeXXWhpMFIN4obsm23BejgWKbxwKiDh_bINSgYWI9y4MoVeQ- - X-Sonic-MF: Received: from sonic.gate.mail.ne1.yahoo.com by sonic305.consmr.mail.ne1.yahoo.com with HTTP; Fri, 15 Apr 2022 21:21:39 +0000 Received: by hermes--canary-production-bf1-5f49dbcd6-b5q4c (VZM Hermes SMTP Server) with ESMTPA ID c91982c747db758d7776974a874b1b0e; Fri, 15 Apr 2022 21:21:33 +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: Fri, 15 Apr 2022 14:17:40 -0700 Message-Id: <20220415211801.12667-9-casey@schaufler-ca.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220415211801.12667-1-casey@schaufler-ca.com> References: <20220415211801.12667-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 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 Fri Apr 15 21:17:41 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 1617938 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=I5DNNc16; 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 4Kg8VP5VKbz9sGt for ; Sat, 16 Apr 2022 07:24:45 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1354460AbiDOV1M (ORCPT ); Fri, 15 Apr 2022 17:27:12 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43342 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1354207AbiDOV0s (ORCPT ); Fri, 15 Apr 2022 17:26:48 -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 E060FDCE30 for ; Fri, 15 Apr 2022 14:23:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1650057791; bh=3VJ6drxV7v8cy0e3EmrY0f1OiWSC5vBe0nWMsh9nu5A=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject:Reply-To; b=I5DNNc160wlbPDRoUppqbEWS2d/N3j9JfdS6ddVqObzNHnR0qAopl4HT5apX/AppU81bksciPa3lp2ahQaF0RwbRzDjZNR9IAtkJglkDl25oLXCdQxsN42TkZTZG6z+BYEVvhAeARKL7/yVN3O296zSyJJZzfoPCGMLgiu7vju/lKOqB01+GAi3rgWEeE2BbhXfj268ReKfMDt5qnQnaa4A4dSZtRuEXRflopX/WuW7JmB5iAb5kM3kaAIKqzBkuGiQzA64k5kAPxofIr8zwemvHByt/FM61qJIfTpc3niETCMHKYhFUyPSncNPckmTdYbn9K5LnK49L3B1D6QMmgA== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1650057791; bh=0/tLYVcaw9cBsh6+2RMUm9tqnYiwPHeXc+UNP0lVriW=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=dH/HNCHk2qs5lwS/Q0CLheATr8B7OOogTiE1TGT0IXiGyNe16skeEo90Ryx39dsFm3AaPQPuCGGr07hbluPCPYWFT/SsEu05CTrcrLKRsLJ6kyqPkFi2006FRWWD4fYsHxYAB8IIOUE/qYIO5kOzP1WJY3aCJQptvcUoaRpGEqr3sQzbavAQlZ6n+oSzy8byLV93D460h80Bb2oFvMGtPpsiWd1v2Hf1/oQM0r86XSK8jzyAANZNDV9TzwySdOjbFBPjH2CpBV/e58e/orp5S14KoSJ4bcM2zAmIUHFywyNwrSHwWjlNjkhzq3/L2JrkGxgzKezJlRwMtVPrcNOtww== X-YMail-OSG: Drz2N34VM1lPc6LxkAzxwvkkfGk4rVQ3Kz1Ds30CCdmWG.8TLq3iMIvWJhSPFN7 VFM1UWGV69mlBpDX6BXfjESjFILOqyZJOcEaIndgjTvr5rDD0.goODdNXAwEYlyYXaaVT4yI.mtI 9apcW_w171ff47fsHrZATDFjiKKNE9keEDs0rcDLc.4O3QOK1Z1HzPDL8R0dN2qZ3upp.2skYxCg sgebMTP6GSlW6Lo0PP80Z48IeBm5n6Q5kaxdJlO7j5KflZanNswFmI4No0.0GmvUHytIWusK.02N dK6emeqJ2sTV3TxZ1D2YMUzszh5bCQZOdIl0tajFShnuHGmEjGGqFV_eVkUbnYFL2hHQTikzAjUZ nAWE0LFXAR5WrikRL._QN6sMh0O1Uu655kDewKYTrKtIBWPEHJGJnmH1nhteSu1ZvGe7_IRMNdj1 QxfQdmNT3qiS4LgYccD9ttIwJOijSVjrMiym4tTMEmbDo8UhiWJ8uUY8I8Ts_ZCaIr7bDqs9rKQ1 Fv7tZmsErQy7PHDlFuRtpVttqUYEmzQOVX47mKdMPpQDisPrX351C5_p8GqDn44jA12DFvkoKN5B 0mQu2aNFr_bun20v4i90CwVuqkW8XjYQhMfoAR_WGtGEKrsF.nIwzyFcfQFg27.rkfN2yLfCWQkU RVnCDNmQDfQn_8P2ZDoKO2Y.EgxRk9RhdOOt3kfE4bgugbAXpMqVC6Hz3SjnWVHn6PHwc2gNnDCF NW.X57umHxRIbFqIVbEti3Au9.8blCzlcv7emqRutZ5.HQ8r7MX1LwEOZ5s8eU9UCB9X7M1RfcVU x_44oer8OXXDdtsK1uaqGf5HBbWAEnePCuVVsNMrsxN3HjdRjANlCuKnddwNK.qIEQYS2AHrkU4r HZsp6UpHgKVutw05Am60TWSV8Um4fVDOpCyfub87K4k0B3iGdGoIbdsGI0Gakor4X.ENg3sTLhf5 hbspfhI2QVUdBTojd5PPsPC9Svc2F3j49vhh6vT._eyO.IQgr5T4fAtJTWxs9WA8D5.txMXEn7EI FEqgjLhLXwNCI38F2yHFdB.TEGEWi8_z5mgO3Ef502ZCBwmyxPPOCKgrWB6d44QbxbVSq3UAfCqq Tlt9VLRY.exd1JcNIrTDf.5aBGOvYFCBo1_K0kL6OGigrp64s44sXDFWIAlxftRB9Zy54YtzQqZy PeN52sZgG1AM_LawBx80sLpCCEx5bS49x3kP8QX497L_jimK2N5Tcojg8xQM.lOgKtZQzko1hJPe LuNcUuZcpjfPC1JCqLO.CTCFechMENe_ZzRBwolmlrss3vb1Bb1C3FWCW4ILcYKDxdKp.kEb0a7O sDie.cwe4nP6eQhNPHAb9ssMTLt1iIo59kGYKWO0_bj4Y2XaTdVsOHefPmQfuLUswIsoZjbxDOqy eoRB_nsQ5JiRFiYUu8Cxa643E6BmrAr5ytkCgjnqqZ6pNs43XEyD_SlLZKioTCKlTSQTRR4Jh5W. 757pUrvwAfprBVHKGD1.x4ftYn9STyGzhmvBwp8dCK8yLqTQ3YvCj_MS55ngIwRXaUaYxQ4to9Y. yJShHFYw2nRI0J1eR2duAanvmT8bY3dQAISrC0b5V1yIH1pHEd0IQFRaGhT8RH43p8tNkfxsUCtM xftNcZWN5YeLUwJ5.vz88h9d.7e_kYoOzAOiaZvkI5VGJHTT1h6ejHhHEFVbGWkFZjzr5byTnLsW .l39ubL8NaeggNklYlJDDnYIGK1S3sBDpDBIotugGyWgNQcXt45Iug3vY3JhVQDRX0jehvFteO45 A8f9a6raJ7EvYH702TTyCcAwBlRqQMKQhYmyqzPQjKnS5cxC.e2zj1t_yd8ZWKNkxsXY3WgfB6am PYKv73Qh1L3VcTW2nXtTEHglgNt9YARDbc2Qm_vI0lddkFRqxhLtScXUTVIuKUmSVu2JrALhQ6S5 A6CseMhRBRPy_TuaJcE2sGt5S2uk595j3yZjfeMaD28HjmM0YYlWT1vrfeWgrot_9DwJ7eeGQbmP fRUmUHkI7evgVIjpl_KVqodNezr2sVrhWhY5u5AGjZwKLioLpe4rbM4h_ov6JTw0IwKKqEf2mdxc 3JC7cStZZJqrbysF_OVboATjtdHLMzI86RnJqx3J5y6JJUe6VfR_HfFKADKL_1Uy19NwqI40Fx_6 kNQcZYDRyykkb1TbyQc7bqWlQK2Huic0a0gXdC_PFdaZun8aXNhFasL7PnyF._ImspOVJtgsUj49 59HpEVPQU7S53Gxh1Ai451MiXMZh35IiBypIOGk4XhpSKzOq8APD9.YABxmGi1uf8_hHyZhvaXmV w1w2L6UmQkeYn2jDx8wEfDFhb X-Sonic-MF: Received: from sonic.gate.mail.ne1.yahoo.com by sonic311.consmr.mail.ne1.yahoo.com with HTTP; Fri, 15 Apr 2022 21:23:11 +0000 Received: by hermes--canary-production-ne1-c7c4f6977-9gvrn (VZM Hermes SMTP Server) with ESMTPA ID 0aa251bda2fc204a3bc01b852774ce09; Fri, 15 Apr 2022 21:23:07 +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: Fri, 15 Apr 2022 14:17:41 -0700 Message-Id: <20220415211801.12667-10-casey@schaufler-ca.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220415211801.12667-1-casey@schaufler-ca.com> References: <20220415211801.12667-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=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 Fri Apr 15 21:17:47 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 1617939 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=oaWhSOQq; 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 4Kg8Ym2pBtz9sGt for ; Sat, 16 Apr 2022 07:27:40 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1355828AbiDOVaH (ORCPT ); Fri, 15 Apr 2022 17:30:07 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45996 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1354810AbiDOV3u (ORCPT ); Fri, 15 Apr 2022 17:29:50 -0400 Received: from sonic317-39.consmr.mail.ne1.yahoo.com (sonic317-39.consmr.mail.ne1.yahoo.com [66.163.184.50]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 783B3E09BD for ; Fri, 15 Apr 2022 14:26:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1650057986; bh=w40bsvxz1maTfxCP5OPrFydafSqo7FsPfYgUwwtQr5s=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject:Reply-To; b=oaWhSOQqIp+rGNYrrZYea0GYlJWahNtcVJXx52K7Q1T5ih0jUcgRAomNEe6IgKO+JzKhb479tkPrm+kJEahXZnxkB1gpppVZGFem3AQwMt4pFj6nhFi/JxDMKWDrXdVcQFBfjSr06jYACcf7B/9u2p7GfCxGisyYIuqRTJQP5zidaxdeALsJ9Llj7WSXtywcOUmZOEe0Lr5cytQeWh5xChNGVKA9fm3ss7AgC05rF6grEMwCVS4lhsiEeRI/nei4oqY0qR07tGfilW88Rq1AsuBXrhuRmBVINX3KNTe7uzt0DOOK3IByMNVDZ4tfQuapxVq3GI0y8UK+TDJVUrNqTA== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1650057986; bh=wtsVw27xPLxCqSUmhyj2kv6qS02lu4MpXdzUpNISyxE=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=b9EgObqnQ4SxI6ZMwLUpCiyZ4v2VYkyjGZb0vSer9vhKiQbR0O1BHH7iosdIEPjUOimgdIF8cE2r361/7AbFGFmA+bhGs5HoAHGXxxAHvgVsQ6dTCx5hPA/zzecqk1ZXZwP5G0gXttvuEnzbVDfWASL13DN6wYrk8oy0lkZMJdsfst+agvee3q1emdVHgg4rHaEJQo6JuRTTslBAe5GCkQzI1pQmGiIhmua7x2IfzI9hRQSXjV1KZwnKAVnEGH+omcsgxOUk6KNzFg4afJ5EmH44a5mglvMuyKMK1u5ooqpoPao1F0UNr9cppLeiHqCBWdlQNlSdJXS9shFsTiId/g== X-YMail-OSG: 9xZ8PEoVM1mW32.vc1fypnK.bH.ALuse3KHHMY_77QrA0519_TtZjc42HsYa89m Gy1D8oYYEjwGVRmX_7AK..rnKetjAQq3JPaQYROyEQY4R5ns6tq.rHn.czKbtHY_Yqw5Hm96JpxD Y6SqVXhqiLfdI_4NnWzFVFN1KmXzBfCyq83IJZh1MNWCpUFNy8P674l5VkCLW5CGWXH6Wg5M4bkn 5_xaF4nXr7aflAuK1BXQG3Iea0oWEEj8j.4jELzgUXTgpvJKUtE_X4p9mnTRt6NluHBmlwCCYNhQ AvFSnwHutgrf8i85SfqTAE1S58JR3FsbyBB6pBgXwCmkBAW58hdOLIXK9IpjfJM1jx07CC5rBHSJ y3HqpZzwDjj1AKije.I0WfE89pYkOvRnmQJOK1Gdam.nzh4cTkoK8dsYW8aFRZTQh2h04DGRZTbZ 6b.eTH.55q_jsXMQ_Rh.IdxLa1KppPdo_Btb_oqgoxb3pphcWmdYhjEkuPGvbC_OD43.EJDEUPyq 9J6ilPF9VKgOk5S8att5m4sasrH7qHdM05_GDVq5OQAPZsj6_npGvYemqzdBQkASiUVFxOEyUfwb yt1R57t5Gu2wz9C.UeACW3UL2OJFmKn4rArEy1IWtpr0cR2qIXmfXgd2ZEuwZD0aNI6Sx.4b5IFE vc0f8ax55H.EJ40RxDaY49yhhAKo42SLYe0MPReniJaIvkEoXLEuX1YnVSsF3vQiI6onJpenuskP PYKEsYUjI93WvUFrAlF1ypcRO8Ko9a_LfJtRcXczAl7nScMogGpIytloV.5coObgyi3D8G7gXOyC A1o9hkzaZCzUrEVOf6RYrzs1QqBFK5.iLBuYQVezc8KF5JjFxA7xOPoFUez4I9zn8h38xQOVhCOn YLX0pe7dAQSBLR.CTKmPP9A2maqCcJX3F05sIBTayM_.wVek13hisuzvCDDCR7x8tTmDVVqcDR9Y pQ.keSVQiyL2Eb3X5m6JnUmFKIEYLZHVUULnnZ2CcvHuP5I.mzwjB4QSFYturfP9mqbtVbmqthgn RG09BwH0OWqftvEh6LE8DVzgNOqEy71RD6VbZN73nfjGkwfLxvjS8aaUkLGii6BbdJkGwl8zDTkM bBf2XFrLDYDu6p1a5u3gGGTkVj_PGLAxwOuGsJReKTwO8Jhr32dmwL5pdLMFWMG_FcGt1xYyebcI 5hwme_TecnhZPF.nRYEUPvKK3ncVcSAYJDl6yLxEQtsn5TBMADH3pMclUqao7WIHS7eOLYRABsmw qFn.PKLS.snJ7HUEX52cP7YYWpR27738ycMd4KMAYhZhmkwzR3B9uBEbnRKQ40g5ySoqIYMTPf5F 8akn2qMK05q.y1keQwVdZyEo9ZUYg3GbmF8hqPLk3fqWUSguC3xTXnY_GU.RHaR0pypJuTOAwmUH Xr2BG8dWcp___ggl_IUSxhbLYV0tvwG8JANi2pzl6Zm1Nq96xq4p6BvphFTCi0GpmcmC66F8maOR GwFIrKxzItNje3Ho0xvjWXM8JH4vGPh2b.Nzw5Q8uwo2fYFwQiFzQH2QlYn9sLPnj2PdnrVTpfgi Y5AIfKZ7aBB7le_YvvinWkRhz5EsMwdP8bh8r2E8IQhmNv8JTLkC1Sj6XLrzqientNtm6LTQlSk6 OkAH3Ug1adE1tOdL..LXViHXzhLeV_qY0UGFOtJY6NwpCdrALzlbmPvhLd9S9Pruv.1Nn_NWV5MU NFVc8_rY77UKOO8aEJwNRE6Gsvo36G_50pVvdp7K7ACW1kcCkgwxDo4xutIegzao2MEmzMC8sxVR hBLphO1YG.B15FwBBrlZ2zFPS4hRfZ6Owdr0PhjMj31BhgNZQ0D40w3.qlPpN6JgcEtjYQj0d36Q dv2fkubweaxDaNP4YvdVUOJXOFExPpnFUM8c7fV76fVA2lm58ZpEDlWC5ma0vIpDRXzlK9Hrq.GF itlNMm78cxQthfMEMV2.2ERD8Tu9DtgKeLxXfyLJM_npMrWQflBqk8TeyWpdAjjbovsqN_OD0yHA 0U1W8YB5HDzxgUmI3D_uk0R9FJj0FCqtV7FRl45mYV19EMR7ru3wSV.9gOBD7Rz4gBI4u8oE14AM ekLgstzIYk1dNKQ2MUHZCeuV6NRvrBT4V.73_hPmDuAD5OyJyRxJzGFdRcNBWdvE3dQ94xA8GAZI pgOJPoLo9vHJ3neRvpotByRQIBKWcrYj3c0jT7Wfr96GGMlqR5zrREKpDNLdftzT3mY_Fx2vDs1l LK0x2f2TIYuejTdz3JbmYuZYmYT_PpPIeavBc7XaADzusMyWtEJ3s1aEyK6lC923IITCwf0K1CGL 8UJt8jso03ROxIY_wkPrTcmkcJJfgMFk- X-Sonic-MF: Received: from sonic.gate.mail.ne1.yahoo.com by sonic317.consmr.mail.ne1.yahoo.com with HTTP; Fri, 15 Apr 2022 21:26:26 +0000 Received: by hermes--canary-production-ne1-c7c4f6977-8bhqd (VZM Hermes SMTP Server) with ESMTPA ID 6a671e6207f140a4363de0fabf2a4e74; Fri, 15 Apr 2022 21:26:25 +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: Fri, 15 Apr 2022 14:17:47 -0700 Message-Id: <20220415211801.12667-16-casey@schaufler-ca.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220415211801.12667-1-casey@schaufler-ca.com> References: <20220415211801.12667-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 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 Fri Apr 15 21:17:48 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 1617940 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=s6JuOXKL; 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 4Kg8Yt6QYkz9sGt for ; Sat, 16 Apr 2022 07:27:46 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1356006AbiDOVaM (ORCPT ); Fri, 15 Apr 2022 17:30:12 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57434 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1355968AbiDOV3v (ORCPT ); Fri, 15 Apr 2022 17:29:51 -0400 Received: from sonic313-15.consmr.mail.ne1.yahoo.com (sonic313-15.consmr.mail.ne1.yahoo.com [66.163.185.38]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 77B73E0ACB for ; Fri, 15 Apr 2022 14:26:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1650057989; bh=9tuF5SxNkWWTGOrRIuV6AzZ33ET1GEIP9udDQ6mZJ1E=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject:Reply-To; b=s6JuOXKLpfinxm9nD4UJRfK46RTSbjGAHse6jLjBvSjzRKGZ/vA06hvmTiVVbUJysTNNoKgmg8IHYiyNxZCIuuUfb7pZA4cBgXa433iW99grJXCJ/CYr6L/G/30dX3U4ssxiXMa+dESxmDsMaZ9YO2KokWHA86v07vxr+XaC+Md8RmAqZJp0FX6ljFh6LWFNEX//pD4pTYG5plrO4F0iENFo2w83GhI5ydgFoBgbe3zZbFBwlFOEfUiaeR/HDQPJwOb8RtSX0+g6E+mCKzpFvgHjHagblO6FX1CSmO/HbngPNnvPOs2rb3jtFTqDG03UlPhahVKEADZRTUHe7lWjFw== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1650057989; bh=7iDjP/7gKbIfdfjsCd8J0ANwrmQgjv83qU+HCSnkTYM=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=mt++bO/0FrKcKXBKWojihVbwsTMwV5YlGgN2bwUjO+/HwNuvQ6P+uA6xJ1E7tHycvufwAIAhTJBUDW7tbrUMMu1r72BQeL4zvyo6UC6hAY+L3FYLFUkq4sZlgW5jtCUbBBXAoEPqPbjsqvDloy9z5Av3kj1a8ryxYu/8ZANZ8GqO+esxV8fxxdQfkJ2EtGztWicf6MmP7ktOrC2NYeR88z6ejXkGcGulrlFNsjoJvjAX7ZXwqpyJ6XxtLKBwOOYpOnuGAu8NCXp5t13QnuLhhsAVYJr8ir2H6kO9IefxFHbpxOy18Q+uXZB3wFwhncRLlzG01+XIT/x3cumZqA3ntA== X-YMail-OSG: Bf62qA4VM1li2IyZvjYawfeiuw77v3QReTzuyEZkaNoA2wbMq08.29XUqqxIUYj 6_ux6od2ct9vLXXirJQ0eVc8v.3XS.yGBkYk5oFjFlI0wJYrNgLYjjycHd364Vn6ygPuUjDUpqrO 9spO.QoT20R_2Teqtd2rFeVtW_PW_zWhQaDJ44JeUg0Mw0RZ0aEy.Gf8RLOPz2j2Iav2dUy7JH8c gAWZtnFQl5Ye0vmG2oUoeosZ4OW6169z4azTMcwgabDPby.ddkDfxH3aaTnFuY8iKqe1Uyb5FQ51 urgVgg4zbyhv6lfFHcCuH_HEnRoVjThS2J_9bLXhbVxNaoNRWVjem90KKRaZO39rIi.iI3WRR7gi MoyINdRUEke.dA9txQOz1qaZM5H5HaRH3GtEpW0KQsL6o5KtifWjZ1rl0UOaghnR3sXFhx3EEQJt qOV9rW4XiEBPUwGVlmN7HRlTkZwrWQyr3q8e33CdW7QyFFmPGzAy7dkq30g_R4PyiTorVREWfvM8 vax3yQmlzEKqtSMBJw4ByYPhLqh9krfmKlp5cIn9Je1rOKZSgLdKZXk.47ax2_.sQuIq90b5JIj1 pP2.ummDhs2SaorAMPDw1508WhlvYq4DQcTQpcX9bP2fErKl95DPf9Oznr9AwqvQ6MWBarzVXEcc a43OHpuwcViSzE4aClqElt_TCmzezu.Vf4.dxLY45zKNxYSMUVxJlULwGORSb2_JVgL.Xw722XDr Otm_l7pzkDeAESpInw5jdIPmErwqPgQZ3SNROQFpr_nhfJ6G9Hb4wk.huSjHDL0tdy5y5B5KVDBK KaVn0kV4m.Jl69gdKuhXcgEE2JXyuWqSSgqQThQ8tOxu_iQViVNyJeCl7OxpQIKGj_ydno9sfkAi LeiEWn.9zttOyvFGZEFUNFeKIUU1VNSsbASfMmZO4Pzn4FW3IYx9VKn_n.LN0cHpqw03k_3r2f8t SfQ3osTRk6VxJvyfy5ekDn3eYVTFISPoqUVM82OcNac9rogL1qw.2A5_TP4dMQB5aHokpRJJQJ1N tIFov42.HGERvQu97gjIqjhUJ873iH8ZCtd5SpNiXK6.z_ziN_Sk9df9WhrlZcHKMtekUgzoZJTg 1H0wyDpMwjIrqR3I9oEirZtY6JXABaf6xiJxTh1bfyxvWhQE5yVMl6Jq6maQ0_2W78KVb3QjY2dy fy5U_FclsAbfdbSEAo9vTv2qBMIJlzMCexozHNY8frDJOe0SoqJ6MdOTzNIYimC0XxtRtU9Flmmn cbaYp7JH1N7MTUa2ByUOX.F7jod9G42B30FkZxgzRb6AzY5W8B.wjXR7WS83PCnCcYXySQPkdcS5 x3g42MFY3mcuhg9zEwG3Y.ezciALEkl1N64_k53lNMNDJS.L0Yz7_bCdv140B8R6cbVlAeXe0Zxu YDwM1TauZfp0v0WZJAUKCU7lJp8ZcWeyN.WD6l7RPGrEU_NHBrY3WHXLiwQof.ozWb4qP0STLtaD ULaawVIUoNzf8AKdqeDnppDeGVAtKQ4O7DPJe3fafIgLqDm6QWuba0s0HKsWZXKuQ.EwKb7cbMQM x_hITif0WEemsl57Pabz_RrsK67rUDZEQmYWKDQeSnHSpil_5cWFn.Vy67pqIJ5i1A5jz_2Zauo1 bQbkZEVAzrqbaUJGNWQeqPp2J2Wwv6ThSxwj5SxI.SsJkDcxO6t2PLQ6wTZnG_NGymwSa.N5POeE jbsRib3TaSiprBr0yzL1cqLGVf9R_ClxfnYLfLFwkNb4Hl_5cKE3zjoPgHgL90eZCbGkWkD5J77l 1ZySp2rx79qr8BUhqG1zBst9AzGIRuPWz0CdawCR1XYOi9LP_cMA7EwV2DKJGVTPjUSE3GqAMrIM 01AdfxF1TF7W4xx8WFRBP6OTuAe.5EBQklgH63SA0WTN1rpwlWR0lm7CJiPouxHusW4iD1JyUY2K hTA0NYjkQdhjSi5yG3KVnDljQs_QPKHrvHH3CTY0UW15VvLZrzx2y.9e3UcNrehUbMN2DplL6ibZ qQP90uT95qVRk4jYIYyImI_B0P0C753ykRpxPcV_nNpq_1waxmZVo6V2GCwWLBBxYOj37JRIVd2. blcWbBSkYRf725In74cdnvZm2Fxwf8jbst52hUYPIBGNs9UNe6CYZi2CTskT0oLnBpM2Gix7ZWSw ODLK6p932c5VkfC8lGkEPBd6H2bOLmAkbg8CopxTk_gdxvPjA.8BhHlwq0M2Ui6I8uIV5TTXbTmI 9MA9kSOwOeIGwshOsK9VK726pSYOSenhUubSXA7AePCjsNjExg1FrmP7XFHShBScTvmFMrHIcujk oAPNvIPIiCQlJjTmxyQlBBIRLgIs.YpaAOE0hWQ2VrCXiqtW.5vlSW3znn60YUpOUUF5LJIanVoU 57eY.Uqy3xw-- X-Sonic-MF: Received: from sonic.gate.mail.ne1.yahoo.com by sonic313.consmr.mail.ne1.yahoo.com with HTTP; Fri, 15 Apr 2022 21:26:29 +0000 Received: by hermes--canary-production-ne1-c7c4f6977-8bhqd (VZM Hermes SMTP Server) with ESMTPA ID 6a671e6207f140a4363de0fabf2a4e74; Fri, 15 Apr 2022 21:26:27 +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: Fri, 15 Apr 2022 14:17:48 -0700 Message-Id: <20220415211801.12667-17-casey@schaufler-ca.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220415211801.12667-1-casey@schaufler-ca.com> References: <20220415211801.12667-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=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 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 Fri Apr 15 21:17:50 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 1617942 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=iGQZ+LRF; 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 4Kg8Zp0yXzz9sGt for ; Sat, 16 Apr 2022 07:28:34 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1354932AbiDOVa4 (ORCPT ); Fri, 15 Apr 2022 17:30:56 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48020 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1356099AbiDOVan (ORCPT ); Fri, 15 Apr 2022 17:30:43 -0400 Received: from sonic313-15.consmr.mail.ne1.yahoo.com (sonic313-15.consmr.mail.ne1.yahoo.com [66.163.185.38]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 42403DE0BC for ; Fri, 15 Apr 2022 14:28:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1650058084; bh=V+vPgvaKFDTnMpIdljAHcVYg6xkRL77vK84TmLoWvrc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject:Reply-To; b=iGQZ+LRFBHHEB/oXHoRwo5VH9Mr/sw9h5KyxGotR1w30JnJVhwYM6afjVmgaTE05gU1p7jedJ/l0Vpkh1Ar6wxnA23vJ/Cg61C0bkrizGvXSNiZMIXoVmwse5UAyIu/zOm4z2De4+JQDGksyS0nKErcDwFAPStubMnMVp10VIBHx3HO4bEFAa+Llu9fGMDQspVf4Gnw4H+wWhiRh+GuWH7qY6tvfmsT30BsZdu/eVRMfktg3nDpT74BkgWYTmoU8VdBaUjV737g4F88Bz5LnAp5ziQa+vPQH569a4Xoh6pB1hW+/7vKpDLK5SY4qk5hn3+1FkRnNpqLqIDOxf47nhw== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1650058084; bh=ygwtMJU8RS8evRSjtj7K0vGIt2yDry4XIasABzRg0L9=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=fiGcZi5tUXEGwDxNWJ2doDEVJo4UHpIfmBXpBuE8vKFEjQtNxObLnlGNaudt2ph4SfMqdwbfcbrTABgv7hPNMUVcKitq3A9sjG8bFHZVhljM0Ugub5MGH2t/+jIB7tzdblCP5pgh7NJsrwD0PAl0D8Y2ITZPyLmv50Gl6GSaTYIJTxh9FITjzVss56pvVEj8KEoLL497KolDaEYH8JxEOwB7QwNF9ZAlsQEhCB8al0P43wWhJyoC98+Enzi7VGtDSZkZM8TTvbNFSeciQOsN7dc3QzARbuvLx2IqMJZDDdJDRt/yR8g555mzsmTPMCQd3QZh/K5/m7rNPI1OIvGODA== X-YMail-OSG: sWC8LOMVM1lc7FtZ9z7mLtmTRQ5G4ud1yiYC9865FXzg1uaCtF_PkbAqA399YPm AEg9VmFLB7UiJMXJnVQ9izsO.nGo8gSVfMTTGgXuRmUYQkegvmjpXWY8hFESn_w2rRHKEy3FDG4c ufIsFZdhW9Zvwla1talhbOaqLH8qJ8ajP.A74SGeJl3z6QBBW3.9Ph7BmJWUoM1PueinKef092Ng mCbKJjK04atP2mQpZB_x9gGybAzr6QYC1_lnvQucLzvvdiY9HeF7NIvmbLkTrSkgFr.LZy98L2yw j_POslKFhAoXOEyvgsNpVIbGU6TMz4ZJIdaCg.Ub_vD1hMxbBeL1UPBnwqQkaElX1QLkewyJy_Ft FyPXyNycQbKS8hV6LWjA_auqD.UwnBVSZHDpyJsdRXANS6yBQ8HrutukgEnIX5hnVjeFXLwiTSkA lbwUBwwxP5Cgz5W6AJq6GZH1JUY3nlpNkaPGMo45c7OXlEYY3ms9fijNa_GaYTESDV79H9cAMjSC dfsh8Q5iDhUXVsxeHJuTvvXikyObDMORhAJ0IIrwqkIfeKuzWcy8ER00m..gZpG8F85zuHVU8266 VbFnOpVrnPsHu1Rze8AoywJO2ao_i.p_aeU_Oby_5CF.ozyTsY2uWvsIxuGbuOR7M0mrB6h26Rc9 QMYGZejl64tvvwUsVuT2hvssCm.F8rkgH7Lidze1i3c9ZUOia.LVYOhmMjFPbXJRvfowNYGgzobB ..qAtaWhywJHK3u4OyRChFO8TRlOa7_PybfrJxkIRjP59HF.jXnXbBYOuhWN4L2PQjtDKhH3RYF6 SSKh0VlwjGiAD2hx3wbzZen4jjgCafQhqdGcSYM_Z9MWenyQ.mlqlQP9hP3omYS7uyYGR8sUzAts XKSsCeNOSIXA0rdXv6_CX3WBvP1qWsWKrv490FVavOW4WrucRQG9EqEPbKh6U1ly74oxJMMlovbF t19QkxeibZ.tds3hdeeuvOg9NyaJRMqK_Bw8HvtBZq8I5HSIJfdjDnOT2T.bjO.FLk7TiOe5foNN Cx6PApptIA0L4tIBHw3.Bq.McQ7DyuBP4RH72VY0yTtk8Zd8G6DjSLxjTjd5HJA98hMtI3MkoP41 IWq48_bFULQaM3DhMsum8WwDp7GOsJRSz3JfgswiHYCmzBSnjvt5IVidgtqes9mJOv52a6grILNz 8Y7KWSh2uO4.inNZCs6mJ4o2Xn1Q7_oVK1yRlYY7usdJm5TS77Hnp8ZgxOgPFA4gu4IWmOKxDOKI 8mSFRCSc5faFYb9lE3YTdZx.N6WG92yGwlUU5be8NdlGdE9K74uIMmmTYK30rwTgAlvTLj4C3rTl skEw_BLixcN6n3xQNXA_FgvBjMx6EcI9_XnpVX8otgKA1a_KLR55V4k1qWbi1Wp0W1odu0G.F7KC kOCcO0OrjkPfug6hxpHIHGqipaG0JTCUbUFpdOaPiMdSWTdcBF4aR7QoA6626SyAkEpigNvamW_Q nZHDolKctXxqRcY9ZHnQaR0XKtGGjRvQB2n0q7CmhAjeR6lFJ66J2gigT5bcr5t6yVFWX4gfpJSu 8uuY1P4l727HyD.rW8b.Falgu_N2GdS9Frh9R5lM6hu7CiGf2n.bDv7YHzxNguhzOPLIn42k0Sfx UEA3BI2XTf7GyJ4zn3oMwZK.PYoayuGSNca584Jmz5wPKtya6M8PI4rlfT1VgtmzH77R9UVaH7Xl eExVY07mz0Got_obeKcF.2zj03v_OgVwJwrlE4cvSxikn6cTRk4pIudC0SEEknWhA4AnK5PZPQPk 1rbS48X6E9bwII0Js2xG5I3AfuNCsbma6MpVbt2T.yInnTl_dI.B0QPgblTJC0mDWUQVjlMJ_IKB xFIS5qv2ySFMnUB3NHLlyNEHaN8JFEYsWt5BeHrjGeUnAaG2h8Lcy2gzDiQcbvlt_RjiqW75S.jG QghHWZkBWrxkTd4kFItYnDRrE5tQfqnSFq8t2b8StJytLsKjCRgYqs2mM6dRTszPUWGS7erTH0cw t0JdABUgfZ16yyuw9_i3Ho3RXpMAm7XDYniUREdUB0mjcPlpDVdGhO8e5U3r3cR9D8VM80CCVob. .J1F.Qfaesiwx49brQnRlltSD4VKv7E7xM2VpEbRyN1S0SYpCA.K29NPjPtVTuZpf1akawjZ_yVw RwJ4eUwXaOYI6F988D7CdoLchQ1GGJSMO9n6raMDC6JmHets51gT85jC9p0h241QPtX233JuDfkW 1M1s_1m6MI_iqAlNIQhoLOhh16IsRJ8P9eFoWIFvqnjHCKq_NE59OkHeBoB8eI5NJz1dXb.WCjZO PC5q5MhFdMEt9KmNNKulYUx0WKjzWTA-- X-Sonic-MF: Received: from sonic.gate.mail.ne1.yahoo.com by sonic313.consmr.mail.ne1.yahoo.com with HTTP; Fri, 15 Apr 2022 21:28:04 +0000 Received: by hermes--canary-production-ne1-c7c4f6977-vjx2m (VZM Hermes SMTP Server) with ESMTPA ID 515394db5ae32f289f837259dd1f1b93; Fri, 15 Apr 2022 21:28:02 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, jmorris@namei.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org Cc: casey@schaufler-ca.com, 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: Fri, 15 Apr 2022 14:17:50 -0700 Message-Id: <20220415211801.12667-19-casey@schaufler-ca.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220415211801.12667-1-casey@schaufler-ca.com> References: <20220415211801.12667-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; }