From patchwork Wed Feb 2 23:53:03 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 12733562 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 643ADC4332F for ; Thu, 3 Feb 2022 00:03:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233771AbiBCADM (ORCPT ); Wed, 2 Feb 2022 19:03:12 -0500 Received: from sonic311-31.consmr.mail.ne1.yahoo.com ([66.163.188.212]:44987 "EHLO sonic311-31.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232944AbiBCADL (ORCPT ); Wed, 2 Feb 2022 19:03:11 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1643846591; bh=dO+uGR09uRVBZct0wGFemFXV8/PJpFqP6Hvb4gSqVwk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject:Reply-To; b=ewUB4WR6U2hAQ3eQV1Dg57fFcrUDKZz2Dbn9umPSEjJMZAjfElZtjJHVDMstX64830aEuqoFRu6pQEOdXd6s1p8dJDrOkQFOofPoxYnvJIP66N+sTq2GAMzL7JcbKqVogPYk+apUIKT8vWAhddWRodYLYhuLfH/Ggs80StU3EkLiTJ/YefF3Z0ygMKbjCfQdRPKpq4zQ9uZjRWBEAyIs9twtGRXOuzC2Nw9Kc+Sc96Y9xV0bzSCxHmQ3kE1Kze3gD3Ax2/aCCvARHQjA7002r+XX0AM5+RodeZOPPY0XYPuhIGuQl+TLSv29M3XdkyF62aTgPP967zcRz0M9IWhn3Q== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1643846591; bh=341sz0TDnhbFtGoWwVXxgmrFzqB3h9qyOVml8UhOKrK=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=BRsagEzWq7o+v2Fj8BGH+XvnD1Va4zVnWMvjRhPy82uIeFSeJVFclePVR/WDSm8UB/Mu7qMQTjLCYLj4ScgOUVx64P+VnHycIG+I/eM9wyEe0BOuufTxSqBRsF0RVfBgx5KofeXsp3GEsBdwl+qNcftGXaUE5oVdUhPAdtbILn4HvcCPIKw8XyS653CSMWzXO68BjyZCoKgZTbWW1+leXZS1BrzHebbKe4s3NtGlWjrufT973ITpsnakOXTmBnR3GOjX4BXFnVq8L2M8NBBP2mvmBt4OCXHqKHScGtR+QeyjQcZ5mblzgE59qFrtst/VkCOY6cqZ4ZtN0tJTYSlLKg== X-YMail-OSG: oc4bBWQVM1k8AFO.4xZNrYXv.G9N8Rrn3zDmmafnBnTTsvBGAMPBAs1KIF49gXx VanoH3e3ZX4nUfmLG6D5Go8gy14vogcebw9C_NdHKZrvogBbXyrwoxSwBFiPkzC2N2SGBo8XzeHy J6fT__EdS9MLk4JE0F5zy8.QyBOqtbunY0JRTZbIe9QthQwoVeVXlhCgg.GfMNw5qPEl8XYasab0 uN3gwrq8q_gTg.ShmYQwZq6EvfvPA8X6I3ETFs4ny2hWgBEcP.ot2ZfGAr7DBbmQlnjH1oujRHzQ eJnd_.2QyP5C54Czobygx78tQn438lVvnuBtUBkGWZ3RO8kCxm2JpH.oVWCozOGhEclFzmQLqC8x mVRNCzlbURgqGgF0xcqMhIxRSTLhljVGDqHNMKjl9AgOZbGlZT2B5YqyFwUB4a1uoVrOQmZdsKyb _YUXITvZuklY_1WsikPZFOGAfDK_..El8Og9EXcfS1SZmAE2kW.ysP_Lnjor6ONoNoRYHxgR7qLV 65_AxfcOxMaWKaUksfu_2U4PTDN3L.pGScYTsZ5Nb6So0gXWvokMyYcNcGM_pjy76GZaJSQd1IYK djQ8YAN6.dC0xfwT47QHtdaRf7UaltP4sMTVrDlW0Sy7MWHyvF3Hk4fIVEn3feUXqhrXrMEqOLKl z5Kh4UmwLSlZYJMzaxJxfcpAG1cncZb.FY9DqVb.F10X7aZGkxw2jRjC11BHE3VD9YA8YxnxKb_0 s6dMdTGxlKy2b1_tOFPbaNP7HqqDE7hYwc.kpnYZrQdKrqqbdK_jUfRcrz6g.4oFDlxI3LDFJUMc D3YnEITDas4_Rg8utGtX4GuEqkz1M3zZvP590rE19vZCPmTcT.sitpVq.9w5ezAvdhdoZWzE41zr n58wg61QYin7IQyJ1X9j9YPe91SabXrHCdDPzY43p2MBGQxdwcKjN3pTWQopNupinYd8EvSTVbbP 80WuYgyN0W7bhfIttiHTTvemjs5Wg0xSkZKDG_jkzqkKsR3Vv5ai.bl9fAs59CCjiUfH.66eQXvc HZSf6bXPuSifI8pnk_MWiBMu86LGGJtJaW7ThzDQykQ5_yXVKE0iAnKUQvDYsV_jX6WukTr6H.xi SNLjd9gqfkPfI5.rQ1BNUIDwjMen4FZUeAdzZAycm1DIBByRSzo_GNuchD2S6IZxXBK7dn73ZSn5 9sV1FlVDQCQpB3wdqEjts7K2QyB3g_RNPJD4Kcsu_E7l5z_Yn4JbtamDYuGDaCL4BM1NwFOkzXYl NGfWRyAkMNRLpZxKSGAWqafj8UIukd9s9g3TmzUEAF.GPPToVGDby.ooyHr1rOvLVkIw9FbCMjBG f304uR2ykXow.znw27IV8HgN_Jr2LeUhYbpCXWpmPrwguHTMRZPjdp.aBDfP0SFVpWAB8IAomMrE zrOYBLjBvuAZdiIqauLtud1O73eUtXNhOEj8cMZZq5Na1GqpM8UY_QX8ciXM84TTSTI_4h05UxxC MaakJkStOLkO4eRswOnJyu8vzZuBtew4VeGY2tmrZrjnOJloij0R0Ew._CJz.7uEyFwUg1RVwsZr J1cssYvortx9kcU20vcWiyZ9f_.piLNZoI5S7TloRyEs_9fccM3OPFW4NYu2AkeEvHQKMUF2_RXO JXNBUBb1JnwIpTfDZYpmOJQS9PLkfszhVSZySm.ETr_Ffa1qsL_cqlf90CxJIYGiK_CR.v6nXhKw q121ULilAvDhX9OUAQzcDbtu9JmrJfaAVIx8CzVYIcq0sH8wlI0WGbnT8iWDhWukUClQHjZFeuKX ApvQhjRjWAsDSbMBjwHm9OongVkb0r6bBEppD9drl2vsE03Yq9_Z4dH5RWa5R1L.Nnl9LINHKTnM qCypwmh7dS9epBqwAxNLVZkLg4N30u0u02iRWHLzrF1ZnVW7TZAs.iytlKXp4H7Wud.aU5LuShO3 LRVVtWdIJNnvR9Ra7fkYnr0UCgauszRhW7ks2VPP1re3ijsYEDknEEuzIFfHq9kQ6wgyDljt3fr_ ZB6gNDReOfbu6PQlvWCnlQjviojUvOlV0snjo_lw8lcgPT4v6KFcHjTpfimKaUGpX00LtXTLtNUr uLKLLuIKa4Iyfp8xuc.krj4S.fWHyUnJAT1K0XbTHzA6JhghHZMeMvEUAZ4vRBLAOKWpwcWfGaMg 4ee7n0LY0EXD.q6EV5Z2yWHPGKDghFgOCJQ4JYg704DTnl2KVMsiPvjrqnMBvhlY79njkof0ub4Y bqsrzeN0Zwhozua2DZc7TkkGTjokGyNs4n1bE_cGDK7ZABxRTrW.mJioMSLPJgfdsKwcdAFrfng- - X-Sonic-MF: Received: from sonic.gate.mail.ne1.yahoo.com by sonic311.consmr.mail.ne1.yahoo.com with HTTP; Thu, 3 Feb 2022 00:03:11 +0000 Received: by kubenode518.mail-prod1.omega.gq1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID 92c78fe2d759d98c8b61fd921c126114; Thu, 03 Feb 2022 00:03:06 +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, sds@tycho.nsa.gov, linux-kernel@vger.kernel.org, netdev@vger.kernel.org, netfilter-devel@vger.kernel.org Subject: [PATCH v32 08/28] LSM: Use lsmblob in security_secctx_to_secid Date: Wed, 2 Feb 2022 15:53:03 -0800 Message-Id: <20220202235323.23929-9-casey@schaufler-ca.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20220202235323.23929-1-casey@schaufler-ca.com> References: <20220202235323.23929-1-casey@schaufler-ca.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@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 4a256d302d97..085565914515 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -198,6 +198,27 @@ static inline bool lsmblob_equal(struct lsmblob *bloba, struct lsmblob *blobb) 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); @@ -528,7 +549,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); @@ -1383,7 +1405,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 e5e41bd4efc3..a112ea708b6e 100644 --- a/kernel/cred.c +++ b/kernel/cred.c @@ -796,14 +796,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 5ab4df56c945..6763188169a3 100644 --- a/net/netfilter/nft_meta.c +++ b/net/netfilter/nft_meta.c @@ -861,21 +861,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 2178235529eb..0fc75d355e9d 100644 --- a/security/security.c +++ b/security/security.c @@ -2198,10 +2198,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); @@ -2352,10 +2364,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 Wed Feb 2 23:53:04 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 12733579 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7909FC4332F for ; Thu, 3 Feb 2022 00:04:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1348263AbiBCAET (ORCPT ); Wed, 2 Feb 2022 19:04:19 -0500 Received: from sonic317-39.consmr.mail.ne1.yahoo.com ([66.163.184.50]:36469 "EHLO sonic317-39.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1348172AbiBCAES (ORCPT ); Wed, 2 Feb 2022 19:04:18 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1643846658; bh=I80onzhH7yaXfwP7a2cDirDLzjQGllxXcwrQXJDrD1E=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject:Reply-To; b=sl2vn5CsnLhXxibT5i0d9OAC+MJMR5dwimCH2/9IOH8QFQMKj6V918jHwhuOqySAZp9RGuKRDTRq6FybvxzGGwRRSfm2Dqop0InZA0Te2P2e+Bitt8ASCGxOJVo1j+3cyDNQIR+/v6SJtJC3k0h6yw2ZYdjC9SWDS92ywdOnMTZgbrsUpLheaUYdMtyXHFZzOxBtWCXrWqtL+UMLAn7P+aEDm73JV7oIYusC5o91JTPn9DP5YmTjS+Y2J/h853P+AJrJQShfza925dhR2pL0GftmHQGueDskgDq6K6F6g32+aB5bcjOpZZXOz3BmeuIUWnDQc69X0a3j50ghXptOVg== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1643846658; bh=/ZVnweut/G6a2pLmWhASOB1ZcpaUEHVDFi5ai2J15bz=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=Wbe5CpCfVGPFldOyjmNSVbNp5lLHitgII5JUovbVQkZFyFuSb093h55JeruNnuo/VwLvOMKliktaE81bP0U3eXdYQvgu4eiMQ5n3GxQNABD6x8VZxc0lKVHXgL+hdQGM8wYUgD7uU0s31pXSKbQQG/mJkUzNB9bWGJqSwFTec0zSzDm5ZSDUkxEZY0ykAaZENTcOWddAlXkK74osI2BbmsgIAGdqFF8XA7HLtbhsSkwlnlY1+2iuYYFfptk0Y/c3VS4n2w47qx+f00qsEaSSoZEPRIy7bTnYU4X9wG1CGrmIzz7uLM4plvPGfulrxIZDfErdRkaU/kxDjKTXUBc6RA== X-YMail-OSG: NagP35cVM1mFDy6.WtM5HptQCC3g53KyPWLExW.mHWhJpJkNky0hbbLv1Ts3QsI vEgmKsvI3Fr7M0gZrPZ9AK.oY5FzdeZcxckkowH8C7WZwCXkm8yDlxfx3MQ2EGOkMLoVsw2AFeM6 VIeJ0T.fpd9AnU1SGNBimBvOrpNmpyFJ_XjHj8oGUo5pojAtNRVkxBFzPrsMDuqRNioo0aM.EoIT cVTWmij.HZ1FxHfeeMBCKuPP9XA_q83cbJFvfCFykAfVTQKTG6to7NewfeFyfGJijqkLV4aHPfOf 1_qJ9stBzQ7.p2ADC7h1hDkeuPheqkZ0xlbJHr1FCF2O5YF4m7Lv_CV34jxkg0kbN_Raa8tqtH9M 4gyWvyrZy_hnlFK162cwz5RUj9.q5SEzb0.e2Xz8S0SYZyaIchB4KxpSsxo_mLFZxkeOJGDrkHcH vjRe3aJqEKP6dqA9QAOK01RbByUcuIAHmj7SDCLT5I4M51rUiVEaZHdqE_NKIEsJmUUNRik5vtkX gudLGpvUg1gDZuo05dyAwTG4kUyTi6uN2tLORRqy1snnhLWuzhHS2IJLrmOShsnNQHtTlglkEGkJ Z3t5QNbwH542u9U7PQy05pNBtqjihCezewKKKeVv1Di5IRf5pkRCJYDZIp2_Gv9i1IvQiAKdvMmI b5jN8LvT43IxZPfIhfURnJUENcR.iX8Kx6TrrlbYINht_xvUHQwDCg4g7ooDobm9dvW9xCX.wE44 VsKmZm7PN17kXGPSBoj7dfdePKOydRhERWc6SY8FdVUNUsDH0.POt1aEau0MzTsRoE7dXGEFeZVf pwbLBDQnYG52BRXtTMHjjAnU03cYDT9Yn.a80OrxhJy79ro6PpM.dZNdJyFlvHOe50Fxz.p1tsmy 0hjbbBLUkcggy04j6EXHVhgNcbYpsa9N3TlXl9fWB5cBG5tLYbobPOZggr_e7Axp9c4H.Ib75DBb gG5mBhTrmKDbyexpSfPOP.ix4Cu.1QzNiF35l7XRAawvy7E4uH8b9BPtjSuwmm2HBkfqtmCvxdcj ucE52QbpSQJC_eGTlNKO0KwV6RgPJ_9hwlqVdbKxZIcp4A_co05k8oAg.8uNXfRO__mSm7TcQS_I woWLtuAKOPtA.syvEysczblE_LB4QwZQ99hOjGfMB4QRYcXPtwKad80KJO22gP39xel4Y5wiGnnz 63ksOudSJdfsLXGKndhUh3u5zHGefMMxJO7IOkfIeSNosqSO.Fs1xbSpB07ujs79hhly9iLrN8oA 1hMvv5Jraz.Dt_Z6a9l5sHQy7xvitiMPvrTwtpCo6OiqPN86wFbXWFqnXqR8tgIHpwQccIsPa94V petmr4oeFvGLt5YN.yRxF5nnABmbqDsK4MzlIeUlCa.D.UHSK9GJc9JxMo_psiczmvGup4kqAaN1 lGdEBgX09lORjmGsAq_D7Icw1IpeaIr_7PdFXurR42NHrSqYmRG22njPz33WAjJsFqYM_M3loUXx dFx9nwuFcfjFnaCPZOqmsOF2FiCaa5pVR2QZ0IcaV1D4iRIFM30fb7VM2_wHFhdC51JQuV5PkvGa HeN4pMvVSOAPK6ybWkUchfWfme3XgEzyB9OEh3scTWJKQkUFl6xIYOe867Axvl30njZnLMs7VVX7 MPSUlPvfZOHrmwNvO_fO7wQRiNkWBTS0CBLwmLX_fnQGO8ETiRFqPATy6_t_p0plNkA0Cz5sVj5P nS9UXPHsA8kP8LAlkfdagqTjTxqhyMs7cBzNCrot0OzVuX_rVAoRx42UAJkCQJQxM3EnmzDpy.hV BhHvFcvpczqRHiwksS3xa_CLm24QS33hKUzNfccCjSBUvSd1QzIOgwn5a5TXDgwudoCm5TzBQJWO y77yy1xjAivv_Hq.Srl5BDiiuAoVH2.aVethsXlml0gB5SPhvhDxErGGzCFGGHiXVTBfYHorZQU_ 5bWQKWnqx5vLk2xFKTOKOurqavPCLkKSta1.2jDYKLf9Y4p.dNaCJUvKAy.M7QqStTZeiNgNACUK ZsWby5CbXTXZz89Z4qe4C5w1PeUrSMZC.BLG.99xxUuUrk3jTWjgYAc8lZ7V6M6.M5o_bwuOc6ht HcQBI1Lde1M6mcm8eH89J9jUOZJTU1NHzq7Ih9I5x_NG4dOdg20TqDnaRpU2Z1vFKUY.gNcmenHP v0r3FaTVGMSpwXyGTk8kuABjgi3B7YNpTKC3NgtjtkmGd1eOuH8gX1R3IykcswEfeykpzoyW0IFL fyz_l7hCthdgNCAcEXmQROgqq059xCCiAOLtLNlTuJ8QJFuHmLeADJaZS_GtWwBYRaVlUSmmKLA- - X-Sonic-MF: Received: from sonic.gate.mail.ne1.yahoo.com by sonic317.consmr.mail.ne1.yahoo.com with HTTP; Thu, 3 Feb 2022 00:04:18 +0000 Received: by kubenode522.mail-prod1.omega.bf1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID e2553693f3b26411334448521192e2ae; Thu, 03 Feb 2022 00:04:13 +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, sds@tycho.nsa.gov, linux-kernel@vger.kernel.org, netdev@vger.kernel.org, netfilter-devel@vger.kernel.org Subject: [PATCH v32 09/28] LSM: Use lsmblob in security_secid_to_secctx Date: Wed, 2 Feb 2022 15:53:04 -0800 Message-Id: <20220202235323.23929-10-casey@schaufler-ca.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20220202235323.23929-1-casey@schaufler-ca.com> References: <20220202235323.23929-1-casey@schaufler-ca.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@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 085565914515..44843d665f35 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -548,7 +548,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); @@ -1398,7 +1398,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 e4bbe2c70c26..40d8cb824eae 100644 --- a/kernel/audit.c +++ b/kernel/audit.c @@ -1440,7 +1440,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; } @@ -2146,12 +2155,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 e5ca89160b5f..5edb16cb12e0 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 { @@ -1371,8 +1387,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 { @@ -1533,9 +1551,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 ac438370f94a..073510c94b56 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -341,8 +341,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; @@ -650,8 +655,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 ea2d9c2a44cf..a9f7c9418ad3 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 0fc75d355e9d..ffdd366d2098 100644 --- a/security/security.c +++ b/security/security.c @@ -2179,17 +2179,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 Wed Feb 2 23:53:06 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 12733580 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id C48A4C4332F for ; Thu, 3 Feb 2022 00:06:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231229AbiBCAGa (ORCPT ); Wed, 2 Feb 2022 19:06:30 -0500 Received: from sonic312-31.consmr.mail.ne1.yahoo.com ([66.163.191.212]:42663 "EHLO sonic312-31.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231561AbiBCAG3 (ORCPT ); Wed, 2 Feb 2022 19:06:29 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1643846789; bh=EqNFDQMugZeGYTvYoJQnN0P9iZgp/6AR/4bWKU98LdQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject:Reply-To; b=bXmTrmbedLLJ2Ut1FtaOw3ZOFk6d0E+1MFi944Sr25P0uQZhBsAI9tmCqg4e+BlE7l12ul6N5PfLAKYOiFikeVHD7eW4Z01OBqpb0mGw3Of2uXHhdfzBAZ1oxyv1JcZ42JRqNgdwAPQS6JbnrpHfjWDUzP2zGZsmansICQPZwNX49FvnOeIljsIkJyr+Ejkx8pyPAbGZNhHMTERlDMRjw1jkBXSEjli2F7EHps8sqsxNxuU+gM6NgZLrrV5pahJOEH67j1Ay6aU9YpS2x8DuG0C1Zo+fE5yDgzRN+PzRUKO1O1azB1L5HC5+yWqDq5m2Fi3NLuC2eZ84fYALOasfmA== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1643846789; bh=gCTTO8q6tJuTejmmTs4I26sZpe886BpjN8Cmdfr9NqS=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=U1lc08X1JrjeVyqPS8PFInm8cdz+lwZ/gzVeinbXlHgOMf/2l3MUoZ5O4YN6FiVqKdJBg4ssVRNckkayYBDEsvTKhX4n32LnA+VN2pRrsQJbZ4ZnDawZ2uWXumPCilcJAfEGJELl70mE8X/2TwmstsveecNsnbo+kBDfz87XvkWSTzBFe7VZgRKNddMKtbrlZZ+vl1Yy5yBEgtdH0lnWABv0odg98AkIfDFWQMRGQYSHT2/AyX44zpLiMRenciu9nt1JrsSpvliDQDVZZ4Pde7gxmh0qS3sCIEzG3b1WG0nV4NPsc1V8Q4izU4Tx6+Km3418sgXSTHoIS5fqmT4sNg== X-YMail-OSG: DtT5mAcVM1mKx30D2vmR_TtRmwlhNHlZBskSVZW2bEhNHBUDMR_Zb8HXt7ArkV2 OPIsKGqFFgobglSKNMmStyXp0ELbFS0Wpe_hCPmCKifXUxQ8604sM9u6UU.M91eJcyQNX6eJwRMO _BjhmtPMxi6GZ3XFqHdaX8oJbiAMzX0LoKaiB0T1mSAbW2_QnobbNdKYl3isBqD075n8nyIZOoX2 Xk2d86hCLeh5iTG72P5a._0B69nyumfpHwGftI4H91QfD9XmciBo856EDbEhMZsIjiHiZc5ZGeFh 1y0QPTMGGsPzy.ZHj4TnfDqXE4i.hcOFkTnjZSlig540KXQI_FSUZKaQc1Ci0qqXwUP1DB8gFq.B NeaT2GTYt0vuDB7LNUvCicOQUOkma5lRjbK67GEQRQ2C63VT1GmIwC8o9nT57e4fZVR90P45fGj6 Zye5jEKAIOmTAxjbsVeqnV7fKfou9FESDZqi_4H3Nr9.gGCe1iKSU2WiP4gTr1Q2M7gXB.4U8By_ pGLxrTlsjvafzs5xoM.RbkqK87ktc4wjY9dNKzWS3UjKR24aQBJIofuZy3EXUMdlpHJHEONLvrRC HdsF50.7cAZT6Jbpfqcv7Z3TJrk_58jYsnbPA0fcykMWXz6Q0tV9ptLVdI.nWZa6jf4EpYcXMDvI I9L9qp4Dlv5M3N6U1RFYe4PG5mWALqfrByHfc_4adqDDxCpkSH6OtN3GMSRptPJlpbMfn7QB.6On oNPknGvobsbbILcOhmQT7Wl9mepZF0ZbQIySYuyo85klzBcPz.pjkP80sTvng0eCF.0J8DGS_RRx HVb2Cn35vrfXBPfqVd237CHB66.DdPDRfGL434qAZkxlg86yLzdlF5wjS0PnZ4.GE.ronQbPA7Uq .MZhu.r.Xe4I4PjbhgkZb2GTrDoY4pCz7fRDZANi_6OzGI86IJSkt6AGPrAKD3V68iVDROyKqoQ_ UqokZCMbqjKEziYX.y95zMzWA_r9lpv4EcRlHSOqE.hkgYT6nv6Dvnr1gmqCsZ7dgtRIs1Ldv4sV n9zbR48cx6eB1k1Mcu7BKd7RkRf8CWarrml7f1oWOTBXFjEk.3mhqsLwVWWanUFtkRi6Q8dCf034 sXcl5t7Aui8DvON2910ZjJBvIizuw17QtFFGtyBzf4XackaIMjtzOwx25Ltr57mvdv1udFpKRRct KWG3Sm8LyEPHyqaIxYXch3o8bPz9TkBUB6xM8m9.j_HJrtCGjqrBWGKBp.WyFW66uoyzkDHVLCXo vHE3KyRYqkBa8981ciO90mBSUfqul128vaW2V8utH3b4SZjsUOLWpnSqnxstPSVM68MMkbzbfzOJ z3DsbGy4zW.SdsWvkO7L5cz4LZ6kXG0.ok7MSaAAeZLzKOpdN3h4LKw4dEzHeLeb6..ndWnJljLD iFgeBM91lKxXnzgN4Q0D1musB7Tztz1vIrukvaImcqW3MqhZvEAZdMqd2Tv953tvOe_9Cy4CDrJq oqyfGZM8_ynUkSSMtVPBUZhE2v9_itP9OwxkrfE4Du4IG1itteOHS3oWP2TYb64l2tKqB2LUzYfO Fej20.Am5Fdpf4ddFdGesmROe2KFgfWxL7P5kSNrzV1prXjH4z2.IaLDXASeRWN0Gf.vwS1ssWiz _syz3jNfutbYzBSd0Q5VjHUFeIg1.Bx_iP5G1VYTEviRMK3zN8o5kBLw_kCtpFQYaUAcLrub_YqQ uef.t38pXmzvP1vsPsQu1F3C.YvM_DNK4e1vnDRgaoxYdzDLevhKvGlv_mrT7HXEdqntGRY86q5K oBQyJTzlnWBkZumCnvLH_LeePXbKlafNBdVeFkb3ihjzmgaAXFHBRbjACx72ny1zX854mcvu26bu 33QJfVZsO48cBOVzoAE3jlOoeoqjGPBhqi6sASIPWfKbLf.LVaN.Oi37HQxxXFGRhI2nH_HYhJHd ClgNEGVCfMrstun.pKacG7ql2xSckcvdk40QzJQYNqe9EHheUxmiKFVZYaWBIYzOjn3Ui8cq.Cl9 fvzF.MuycZ1hKEvwLLJX_IS_dfY3DuwWvY2JFJfI7pr4eGTfuhX8ZvHcOsznr3clsoclcsGhamYG IkNl9pQt.twmdS_413ZXPApcdHAD2O1aAAeJ2HtXf_NAahG8eDWEYsKTFW70mIx.L3DkPtIjFmoq piHb2q7GO3eNDtuAvSd8oVgKZZgcmf4t129fLRALZ50RqRmvaFBgMwu3cADnVgod75oEYnmai2M8 EjGaqqcTynFSFfudp08_bK78R9Py2XYw0nbK61c7Cnlxnm6IaEP7o10RrilIKxPdrLFPMp5J7JOD 9t70D_Q3becMfxavIJXREisICXOmFZBDTFyCAod9QwdGNecAnsshXf6Jufg-- X-Sonic-MF: Received: from sonic.gate.mail.ne1.yahoo.com by sonic312.consmr.mail.ne1.yahoo.com with HTTP; Thu, 3 Feb 2022 00:06:29 +0000 Received: by kubenode531.mail-prod1.omega.ne1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID eb829be640f0d55663e1620f1812a18c; Thu, 03 Feb 2022 00:06:26 +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, sds@tycho.nsa.gov, linux-kernel@vger.kernel.org, Stephen Smalley , linux-integrity@vger.kernel.org, netdev@vger.kernel.org Subject: [PATCH v32 11/28] LSM: Use lsmblob in security_current_getsecid Date: Wed, 2 Feb 2022 15:53:06 -0800 Message-Id: <20220202235323.23929-12-casey@schaufler-ca.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20220202235323.23929-1-casey@schaufler-ca.com> References: <20220202235323.23929-1-casey@schaufler-ca.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org Change the security_current_getsecid_subj() and security_task_getsecid_obj() interfaces to fill in a lsmblob structure instead of a u32 secid in support of LSM stacking. Audit interfaces will need to collect all possible secids for possible reporting. Reviewed-by: Kees Cook Reviewed-by: John Johansen Acked-by: Stephen Smalley Acked-by: Paul Moore Signed-off-by: Casey Schaufler Cc: linux-integrity@vger.kernel.org Cc: linux-audit@redhat.com Cc: netdev@vger.kernel.org --- drivers/android/binder.c | 6 +-- include/linux/security.h | 13 ++++--- kernel/audit.c | 16 +++----- kernel/auditfilter.c | 4 +- kernel/auditsc.c | 25 ++++++------ net/netlabel/netlabel_unlabeled.c | 5 ++- net/netlabel/netlabel_user.h | 6 ++- security/integrity/ima/ima_appraise.c | 12 +++--- security/integrity/ima/ima_main.c | 55 +++++++++++++++------------ security/security.c | 25 +++++++++--- 10 files changed, 95 insertions(+), 72 deletions(-) diff --git a/drivers/android/binder.c b/drivers/android/binder.c index 381a4fddd4a5..bae8440ffc73 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -2980,16 +2980,16 @@ static void binder_transaction(struct binder_proc *proc, t->priority = task_nice(current); if (target_node && target_node->txn_security_ctx) { - u32 secid; struct lsmblob blob; size_t added_size; + u32 secid; security_cred_getsecid(proc->cred, &secid); /* - * Later in this patch set security_task_getsecid() will + * Later in this patch set security_cred_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(), + * get the value returned from security_cred_getsecid(), * which means that the one expected by * security_secid_to_secctx() will be set. */ diff --git a/include/linux/security.h b/include/linux/security.h index 62178dd4ec08..d7781bda147f 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -501,8 +501,8 @@ int security_task_fix_setgid(struct cred *new, const struct cred *old, int security_task_setpgid(struct task_struct *p, pid_t pgid); int security_task_getpgid(struct task_struct *p); int security_task_getsid(struct task_struct *p); -void security_current_getsecid_subj(u32 *secid); -void security_task_getsecid_obj(struct task_struct *p, u32 *secid); +void security_current_getsecid_subj(struct lsmblob *blob); +void security_task_getsecid_obj(struct task_struct *p, struct lsmblob *blob); int security_task_setnice(struct task_struct *p, int nice); int security_task_setioprio(struct task_struct *p, int ioprio); int security_task_getioprio(struct task_struct *p); @@ -1198,14 +1198,15 @@ static inline int security_task_getsid(struct task_struct *p) return 0; } -static inline void security_current_getsecid_subj(u32 *secid) +static inline void security_current_getsecid_subj(struct lsmblob *blob) { - *secid = 0; + lsmblob_init(blob, 0); } -static inline void security_task_getsecid_obj(struct task_struct *p, u32 *secid) +static inline void security_task_getsecid_obj(struct task_struct *p, + struct lsmblob *blob) { - *secid = 0; + lsmblob_init(blob, 0); } static inline int security_task_setnice(struct task_struct *p, int nice) diff --git a/kernel/audit.c b/kernel/audit.c index 40d8cb824eae..17ac6e74b5bd 100644 --- a/kernel/audit.c +++ b/kernel/audit.c @@ -2154,19 +2154,12 @@ int audit_log_task_context(struct audit_buffer *ab) char *ctx = NULL; unsigned len; int error; - u32 sid; struct lsmblob blob; - security_current_getsecid_subj(&sid); - if (!sid) + security_current_getsecid_subj(&blob); + if (!lsmblob_is_set(&blob)) return 0; - /* - * 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) { @@ -2375,6 +2368,7 @@ int audit_set_loginuid(kuid_t loginuid) int audit_signal_info(int sig, struct task_struct *t) { kuid_t uid = current_uid(), auid; + struct lsmblob blob; if (auditd_test_task(t) && (sig == SIGTERM || sig == SIGHUP || @@ -2385,7 +2379,9 @@ int audit_signal_info(int sig, struct task_struct *t) audit_sig_uid = auid; else audit_sig_uid = uid; - security_current_getsecid_subj(&audit_sig_sid); + security_current_getsecid_subj(&blob); + /* scaffolding until audit_sig_sid is converted */ + audit_sig_sid = blob.secid[0]; } return audit_signal_info_syscall(t); diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c index 15cd4fe35e9c..39ded5cb2429 100644 --- a/kernel/auditfilter.c +++ b/kernel/auditfilter.c @@ -1339,7 +1339,6 @@ int audit_filter(int msgtype, unsigned int listtype) struct audit_field *f = &e->rule.fields[i]; struct lsmblob blob; pid_t pid; - u32 sid; switch (f->type) { case AUDIT_PID: @@ -1369,8 +1368,7 @@ int audit_filter(int msgtype, unsigned int listtype) case AUDIT_SUBJ_SEN: case AUDIT_SUBJ_CLR: if (f->lsm_str) { - security_current_getsecid_subj(&sid); - lsmblob_init(&blob, sid); + security_current_getsecid_subj(&blob); result = security_audit_rule_match( &blob, f->type, f->op, &f->lsm_rules); diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 598e0de45b04..2570bf5979e0 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -467,7 +467,6 @@ static int audit_filter_rules(struct task_struct *tsk, { const struct cred *cred; int i, need_sid = 1; - u32 sid; struct lsmblob blob; unsigned int sessionid; @@ -676,17 +675,9 @@ static int audit_filter_rules(struct task_struct *tsk, * here even though it always refs * @current's creds */ - security_current_getsecid_subj(&sid); + security_current_getsecid_subj(&blob); 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, &f->lsm_rules); @@ -2712,12 +2703,15 @@ int __audit_sockaddr(int len, void *a) void __audit_ptrace(struct task_struct *t) { struct audit_context *context = audit_context(); + struct lsmblob blob; context->target_pid = task_tgid_nr(t); context->target_auid = audit_get_loginuid(t); context->target_uid = task_uid(t); context->target_sessionid = audit_get_sessionid(t); - security_task_getsecid_obj(t, &context->target_sid); + security_task_getsecid_obj(t, &blob); + /* scaffolding - until target_sid is converted */ + context->target_sid = blob.secid[0]; memcpy(context->target_comm, t->comm, TASK_COMM_LEN); } @@ -2733,6 +2727,7 @@ int audit_signal_info_syscall(struct task_struct *t) struct audit_aux_data_pids *axp; struct audit_context *ctx = audit_context(); kuid_t t_uid = task_uid(t); + struct lsmblob blob; if (!audit_signals || audit_dummy_context()) return 0; @@ -2744,7 +2739,9 @@ int audit_signal_info_syscall(struct task_struct *t) ctx->target_auid = audit_get_loginuid(t); ctx->target_uid = t_uid; ctx->target_sessionid = audit_get_sessionid(t); - security_task_getsecid_obj(t, &ctx->target_sid); + security_task_getsecid_obj(t, &blob); + /* scaffolding until target_sid is converted */ + ctx->target_sid = blob.secid[0]; memcpy(ctx->target_comm, t->comm, TASK_COMM_LEN); return 0; } @@ -2765,7 +2762,9 @@ int audit_signal_info_syscall(struct task_struct *t) axp->target_auid[axp->pid_count] = audit_get_loginuid(t); axp->target_uid[axp->pid_count] = t_uid; axp->target_sessionid[axp->pid_count] = audit_get_sessionid(t); - security_task_getsecid_obj(t, &axp->target_sid[axp->pid_count]); + security_task_getsecid_obj(t, &blob); + /* scaffolding until target_sid is converted */ + axp->target_sid[axp->pid_count] = blob.secid[0]; memcpy(axp->target_comm[axp->pid_count], t->comm, TASK_COMM_LEN); axp->pid_count++; diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c index 0a99663e6edb..c86df6ead742 100644 --- a/net/netlabel/netlabel_unlabeled.c +++ b/net/netlabel/netlabel_unlabeled.c @@ -1562,11 +1562,14 @@ int __init netlbl_unlabel_defconf(void) int ret_val; struct netlbl_dom_map *entry; struct netlbl_audit audit_info; + struct lsmblob blob; /* Only the kernel is allowed to call this function and the only time * it is called is at bootup before the audit subsystem is reporting * messages so don't worry to much about these values. */ - security_current_getsecid_subj(&audit_info.secid); + security_current_getsecid_subj(&blob); + /* scaffolding until audit_info.secid is converted */ + audit_info.secid = blob.secid[0]; audit_info.loginuid = GLOBAL_ROOT_UID; audit_info.sessionid = 0; diff --git a/net/netlabel/netlabel_user.h b/net/netlabel/netlabel_user.h index d6c5b31eb4eb..3d5610ed5f0e 100644 --- a/net/netlabel/netlabel_user.h +++ b/net/netlabel/netlabel_user.h @@ -32,7 +32,11 @@ */ static inline void netlbl_netlink_auditinfo(struct netlbl_audit *audit_info) { - security_current_getsecid_subj(&audit_info->secid); + struct lsmblob blob; + + security_current_getsecid_subj(&blob); + /* scaffolding until secid is converted */ + audit_info->secid = blob.secid[0]; audit_info->loginuid = audit_get_loginuid(current); audit_info->sessionid = audit_get_sessionid(current); } diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c index 17232bbfb9f9..217d20c60e1d 100644 --- a/security/integrity/ima/ima_appraise.c +++ b/security/integrity/ima/ima_appraise.c @@ -71,15 +71,17 @@ bool is_ima_appraise_enabled(void) int ima_must_appraise(struct user_namespace *mnt_userns, struct inode *inode, int mask, enum ima_hooks func) { - u32 secid; + struct lsmblob blob; if (!ima_appraise) return 0; - security_current_getsecid_subj(&secid); - return ima_match_policy(mnt_userns, inode, current_cred(), secid, - func, mask, IMA_APPRAISE | IMA_HASH, NULL, - NULL, NULL, NULL); + security_current_getsecid_subj(&blob); + /* scaffolding the .secid[0] */ + return ima_match_policy(mnt_userns, inode, current_cred(), + blob.secid[0], func, mask, + IMA_APPRAISE | IMA_HASH, NULL, NULL, NULL, + NULL); } static int ima_fix_xattr(struct dentry *dentry, diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c index 8c6e4514d494..6abbaa97bbeb 100644 --- a/security/integrity/ima/ima_main.c +++ b/security/integrity/ima/ima_main.c @@ -405,12 +405,13 @@ static int process_measurement(struct file *file, const struct cred *cred, */ int ima_file_mmap(struct file *file, unsigned long prot) { - u32 secid; + struct lsmblob blob; if (file && (prot & PROT_EXEC)) { - security_current_getsecid_subj(&secid); - return process_measurement(file, current_cred(), secid, NULL, - 0, MAY_EXEC, MMAP_CHECK); + security_current_getsecid_subj(&blob); + /* scaffolding - until process_measurement changes */ + return process_measurement(file, current_cred(), blob.secid[0], + NULL, 0, MAY_EXEC, MMAP_CHECK); } return 0; @@ -436,9 +437,9 @@ int ima_file_mprotect(struct vm_area_struct *vma, unsigned long prot) char *pathbuf = NULL; const char *pathname = NULL; struct inode *inode; + struct lsmblob blob; int result = 0; int action; - u32 secid; int pcr; /* Is mprotect making an mmap'ed file executable? */ @@ -446,11 +447,11 @@ int ima_file_mprotect(struct vm_area_struct *vma, unsigned long prot) !(prot & PROT_EXEC) || (vma->vm_flags & VM_EXEC)) return 0; - security_current_getsecid_subj(&secid); + security_current_getsecid_subj(&blob); inode = file_inode(vma->vm_file); action = ima_get_action(file_mnt_user_ns(vma->vm_file), inode, - current_cred(), secid, MAY_EXEC, MMAP_CHECK, - &pcr, &template, NULL, NULL); + current_cred(), blob.secid[0], MAY_EXEC, + MMAP_CHECK, &pcr, &template, NULL, NULL); /* Is the mmap'ed file in policy? */ if (!(action & (IMA_MEASURE | IMA_APPRAISE_SUBMASK))) @@ -486,10 +487,12 @@ int ima_bprm_check(struct linux_binprm *bprm) { int ret; u32 secid; + struct lsmblob blob; - security_current_getsecid_subj(&secid); - ret = process_measurement(bprm->file, current_cred(), secid, NULL, 0, - MAY_EXEC, BPRM_CHECK); + security_current_getsecid_subj(&blob); + /* scaffolding until process_measurement changes */ + ret = process_measurement(bprm->file, current_cred(), blob.secid[0], + NULL, 0, MAY_EXEC, BPRM_CHECK); if (ret) return ret; @@ -510,10 +513,11 @@ int ima_bprm_check(struct linux_binprm *bprm) */ int ima_file_check(struct file *file, int mask) { - u32 secid; + struct lsmblob blob; - security_current_getsecid_subj(&secid); - return process_measurement(file, current_cred(), secid, NULL, 0, + security_current_getsecid_subj(&blob); + /* scaffolding until process_measurement changes */ + return process_measurement(file, current_cred(), blob.secid[0], NULL, 0, mask & (MAY_READ | MAY_WRITE | MAY_EXEC | MAY_APPEND), FILE_CHECK); } @@ -689,7 +693,7 @@ int ima_read_file(struct file *file, enum kernel_read_file_id read_id, bool contents) { enum ima_hooks func; - u32 secid; + struct lsmblob blob; /* * Do devices using pre-allocated memory run the risk of the @@ -709,8 +713,9 @@ int ima_read_file(struct file *file, enum kernel_read_file_id read_id, /* Read entire file for all partial reads. */ func = read_idmap[read_id] ?: FILE_CHECK; - security_current_getsecid_subj(&secid); - return process_measurement(file, current_cred(), secid, NULL, + security_current_getsecid_subj(&blob); + /* scaffolding - until process_measurement changes */ + return process_measurement(file, current_cred(), blob.secid[0], NULL, 0, MAY_READ, func); } @@ -739,7 +744,7 @@ int ima_post_read_file(struct file *file, void *buf, loff_t size, enum kernel_read_file_id read_id) { enum ima_hooks func; - u32 secid; + struct lsmblob blob; /* permit signed certs */ if (!file && read_id == READING_X509_CERTIFICATE) @@ -752,9 +757,10 @@ int ima_post_read_file(struct file *file, void *buf, loff_t size, } func = read_idmap[read_id] ?: FILE_CHECK; - security_current_getsecid_subj(&secid); - return process_measurement(file, current_cred(), secid, buf, size, - MAY_READ, func); + security_current_getsecid_subj(&blob); + /* scaffolding - until process_measurement changes */ + return process_measurement(file, current_cred(), blob.secid[0], buf, + size, MAY_READ, func); } /** @@ -882,7 +888,7 @@ int process_buffer_measurement(struct user_namespace *mnt_userns, int digest_hash_len = hash_digest_size[ima_hash_algo]; int violation = 0; int action = 0; - u32 secid; + struct lsmblob blob; if (digest && digest_len < digest_hash_len) return -EINVAL; @@ -905,9 +911,10 @@ int process_buffer_measurement(struct user_namespace *mnt_userns, * buffer measurements. */ if (func) { - security_current_getsecid_subj(&secid); + security_current_getsecid_subj(&blob); + /* scaffolding */ action = ima_get_action(mnt_userns, inode, current_cred(), - secid, 0, func, &pcr, &template, + blob.secid[0], 0, func, &pcr, &template, func_data, NULL); if (!(action & IMA_MEASURE) && !digest) return -ENOENT; diff --git a/security/security.c b/security/security.c index 815200684bcf..e33fa677181d 100644 --- a/security/security.c +++ b/security/security.c @@ -1909,17 +1909,30 @@ int security_task_getsid(struct task_struct *p) return call_int_hook(task_getsid, 0, p); } -void security_current_getsecid_subj(u32 *secid) +void security_current_getsecid_subj(struct lsmblob *blob) { - *secid = 0; - call_void_hook(current_getsecid_subj, secid); + struct security_hook_list *hp; + + lsmblob_init(blob, 0); + hlist_for_each_entry(hp, &security_hook_heads.current_getsecid_subj, + list) { + if (WARN_ON(hp->lsmid->slot < 0 || hp->lsmid->slot >= lsm_slot)) + continue; + hp->hook.current_getsecid_subj(&blob->secid[hp->lsmid->slot]); + } } EXPORT_SYMBOL(security_current_getsecid_subj); -void security_task_getsecid_obj(struct task_struct *p, u32 *secid) +void security_task_getsecid_obj(struct task_struct *p, struct lsmblob *blob) { - *secid = 0; - call_void_hook(task_getsecid_obj, p, secid); + struct security_hook_list *hp; + + lsmblob_init(blob, 0); + hlist_for_each_entry(hp, &security_hook_heads.task_getsecid_obj, list) { + if (WARN_ON(hp->lsmid->slot < 0 || hp->lsmid->slot >= lsm_slot)) + continue; + hp->hook.task_getsecid_obj(p, &blob->secid[hp->lsmid->slot]); + } } EXPORT_SYMBOL(security_task_getsecid_obj); From patchwork Wed Feb 2 23:53:10 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 12733596 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 05CA6C4321E for ; Thu, 3 Feb 2022 00:11:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1348333AbiBCAK6 (ORCPT ); Wed, 2 Feb 2022 19:10:58 -0500 Received: from sonic311-31.consmr.mail.ne1.yahoo.com ([66.163.188.212]:40193 "EHLO sonic311-31.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241194AbiBCAK5 (ORCPT ); Wed, 2 Feb 2022 19:10:57 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1643847057; bh=mZMEsUkrlJXRzk7x6lnvfNevhq4wBixRboHMZWPFLrs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject:Reply-To; b=n+GCuyFrJGUSgZHDsjrLtIUDQHyVT3GPM3jhdFWSs6tBZROOJVoYObKHGskumdw4pKJ1PAFUadFbXz/t5nKeNkW5EeTrKVdxj5ysB5UIHK9BrzS2UA6YlPDzs3wh6zztuIAoia6V1/RPfjjwT0KCP5/wDAPjV/c1s6Rk5NzNMwfVWR4dbrlH25tCwOPTkUIs4wivfE6U9ctheZm/s9KAAkfReix/45oNsFNEyK1Dx01pnPYvsO+40ppmtL6Td4mqRkxXolHfmRHSzxXl/LR2SwcEAAjt63odZdYARspz2VX5vd8HwjnsqU0Nd3uMtz3rELwbs/oXAO+b+972jpkUQw== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1643847057; bh=pX1IS5QBDaLFRT2SXTeyQOk3WyRB1Wu+TSbh1TqthBd=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=N53cQluOCEJ9DJdsYOt8p38F9fGB+gle8uuyvPQbZVtx89IbwaMt4a8i2npOlldQK4A21XKiYy8upYWi1Yy0v5/S5Q9km7vnrs3aRsz4si68b6eZ4R9d0wKcqwvur5B8qDz1ni3trHnbINsFRTWvFMiyRdzuEPgcafnq9Wfv4Jr2lJFi74W7LIv3UNJ8MtAsDzWw1wFfqf/KRXsu3YJfttgeoR4M8SisQKLBwBmTCRWaCpry5h4ykrmmQNHcRzRLK7K0Pk0Os03HGF8A0u1SDV4zvpJbhrIFAzjqD7jLECsBGb6w+nlkGCCuE7Glrk6Lk+aNdXO9qLQgwoocDqW01Q== X-YMail-OSG: _zlGISMVM1nJl5L_qz1SRT_kdOvAfqBNO4TWC_6BwLU6qX2dh9hpTEExP0wyJgg o8kePWwXyN5mLO3slTG8yFTEJ4Z6sjxj1LkBnDGuI2ZGhl68Czxbekb8PmpiumX.e2h907.iwh4t SR3oUGh6HBC1uc7jxRjXfLS2RrJmfqgnHwecEnmAVPpUDtnE8pTvZfT7nagqujjPNZdv3NSHHTd7 uqMRzh7rAQmk47ZedGbBtBzBccRpamwG86xFxWxqwpkUbxhUtmwaqTFUOMYfCuRCDAcrSdd7m5ye mSJn5vcvebIi4Hz9RSiXebu381_aMARQRwFvVnMPTkdVdQgUZ3ztYs2QqXYwoENBRyuLdRaPt0_y KWt80nPkoAfeHsaOp_mwR7kP_86ipLs1syL3SwFojkBjFCKDlZ28GBuNTJSPL4hc_4OcuS5QLcNt 9F_sLSPYVqZIuwSj7MvLz3Kxrl3ck8QGvRq4t2xaQXcLvwKH7_YadyVEuXQbBzvt6MpDIu18l0_n acVn0Nl6Hr.rZdQCFXPUh4cC0KBP3Ys7ju8K.bv9tzdrutTcLyNFSwCIEB4i.gAVjXgdbXQ2h2MM lhnppHRl.u00towDyi_e0FKF5HM6Sh3rMOHBiJOuwuPRANvS_t7K2QP_z1yDHwuDyYAuZeXWkhe3 wXDSpq2mFrlIpYudgAOtHGblB9ygQsPAInvUBteo318ow6.yBxyQpYWg0DdgcnXjgSVRlMT9jnhK zIwi4X0R8mm5aiYOv6JqZ6jCk8KGQ_EQq4JPidNTslG5UK4Xah7Eis9B_b9cCu3x8By4uG9ioBXm FQhqs4QrhZfTjvoLbOj2lcJinqVhUB0cWPCT71dDA1.U.0ddCOegUGUBeyYa9Lgvv9SPeqorqsv6 K3hu_008cwugqPhvsNLp5SDG92_wykDQNZO0zqKfzJrd0ELH7qHtveULrPaMcwDeiEp4nzSpBmml RSLhP.VJuvtAITDcyqA_sPGma7MSZqw5ZwlGEKOQ0abJKzuelPaHoYA6wW8GHvCGpSCMP1VpQtEc osUIvAapViFV6.CS3Qt5ALgwIsdlqo8cmYdt2cDtKJzD5caOEimHs7JziISeaz4qN3nnfWGdfIR2 EE2ABscOPusWPx7UAm63wJreje5_wCKA2.qiTxsLoFYSi5TgpsVj6KZRv.AE6dfhWhzCNYUq65.K waUfM9ENSKwg5k2sU6cEsxtBScFH2.dVO9Q7sR09JIF7FcXrzHVeohgH90Bf5giGCfQ6Nd7R7anM iMOWmABcytBkZXsTcQOa8IBh6hDO_O.hhcG0SXM6VrcC6zVSLXRIKu6ij5J9Ht_QBXl_w.mcziCa Pb.MrAaYb4.lsYKlmz5ulkg80.QB7rNtcS7XFxeVzZCXvlOT4Z5DfcOreFQxygr0Q.GzpudyH08v AtCaeCeWLnzpm.QwfUwpRVm_tyvanU43qtO3Yfmr0jJkm3IWMIJVnfZ.9HcP3FNMNltVJAdNAQbN 5m9dlmspuZVLrom7l7WB5bsXzXVh8flCJY03mf3Ht3UxGysn7yW4.WiinZQ72QQjpH5JbTF1AtNA wdAJMMfSaaguD7.VNI.tsK5ISdppNHspCq4ujclFsDdWsov9JRT_2P1.DQ7G.wlreC6xTs2XtQ_I OA1FT1Dnk9i1L.Se6cBPIu.pOJ6EH3oPfNPbXLB7HzBPDiSJp5BwGZZwzGXP1Y.4.KVIuhs83NMG AaXq4iYSE7FexePxwK6HPIxgZqYcFtHNW5wh_IYYizh4hCqxkVnlqWeL59MincgWvBDldOtmMK2I fEWxatlAxzR3CB3uh20jtA2XZ_lSWEU10GUafxofqIhPLvPFSEb13jQkHUOAWMvnyIl_zbAaJtSX myRB9P00EL_Fw8lVxDUX02cNBiefsPQWVcyD6FkHiEsPdPuMqHsyCHrf.pqBHF2mQGkMnh2JbNIN GQi.20avyg5NyOG3Zlo9EjX..HoiCD3K.uQfL2h1AWR.55Zomraaj35iufippTkQXeq284VGRllx PnhgRLfFwbBgfn10vLh9PDcUXXznLwUP0bjW4K1yyEI1qrXaLflGyVmtWdIe8Kuewi2rXVuCepnM GeO6qeuF8oxm7UfhqDgA7RXk.vyNsIcHdhh4ZQYOLJds0D9aj1LYdr.j3r21CxnbMMxKkw1emEdu q8ldhVYNDMwO.NDicXRq.RZrXm5iq_q90jiS3.n2YuGLITUByLua9ulH7AYm8TMoYUqgELfSbsx4 4HMPacyA39TmjBFjqhd6PYu_8nk23cPa15kvXdAr8wAaclm7L0GDm4hPAo4h8offcu0zCy03ZSqw H.g-- X-Sonic-MF: Received: from sonic.gate.mail.ne1.yahoo.com by sonic311.consmr.mail.ne1.yahoo.com with HTTP; Thu, 3 Feb 2022 00:10:57 +0000 Received: by kubenode522.mail-prod1.omega.gq1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID 8eaff6bcc33e24a4673fc3a34be90183; Thu, 03 Feb 2022 00:10:51 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, jmorris@namei.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org Cc: casey@schaufler-ca.com, linux-audit@redhat.com, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, paul@paul-moore.com, sds@tycho.nsa.gov, linux-kernel@vger.kernel.org, Stephen Smalley , Chuck Lever , linux-integrity@vger.kernel.org, netdev@vger.kernel.org, netfilter-devel@vger.kernel.org, linux-nfs@vger.kernel.org Subject: [PATCH v32 15/28] LSM: Ensure the correct LSM context releaser Date: Wed, 2 Feb 2022 15:53:10 -0800 Message-Id: <20220202235323.23929-16-casey@schaufler-ca.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20220202235323.23929-1-casey@schaufler-ca.com> References: <20220202235323.23929-1-casey@schaufler-ca.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@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 fcf7dfdecf96..df2b3bf46364 100644 --- a/fs/ceph/xattr.c +++ b/fs/ceph/xattr.c @@ -1374,12 +1374,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 b18f31b2c9e7..c6237b5ddd93 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 899de438e529..fedc4b0292d6 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 @@ -3331,8 +3332,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 735e39fa510d..72da145c1aad 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 * @@ -568,7 +599,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); @@ -1431,7 +1462,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 c7cd039e258b..5aa2ee06c9e4 100644 --- a/kernel/audit.c +++ b/kernel/audit.c @@ -1190,6 +1190,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) @@ -1447,15 +1448,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)); @@ -2147,6 +2151,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)) @@ -2161,7 +2166,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 c4c3666576c3..1626d8aabe83 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="); @@ -1351,6 +1353,7 @@ static void audit_log_fcaps(struct audit_buffer *ab, struct audit_names *name) static void show_special(struct audit_context *context, int *call_panic) { + struct lsmcontext lsmcxt; struct audit_buffer *ab; int i; @@ -1385,7 +1388,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) { @@ -1542,6 +1546,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)) { @@ -1550,7 +1555,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 073510c94b56..212e12b53adb 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -342,6 +342,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 @@ -362,7 +363,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 a9f7c9418ad3..d986bae1587b 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; @@ -627,8 +628,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: @@ -636,8 +639,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 0bca482166d8..163cf0ae2429 100644 --- a/security/security.c +++ b/security/security.c @@ -2366,16 +2366,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 Wed Feb 2 23:53:11 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 12733597 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 97DA8C4332F for ; Thu, 3 Feb 2022 00:12:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1348348AbiBCAMD (ORCPT ); Wed, 2 Feb 2022 19:12:03 -0500 Received: from sonic311-31.consmr.mail.ne1.yahoo.com ([66.163.188.212]:38470 "EHLO sonic311-31.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1348336AbiBCAMC (ORCPT ); Wed, 2 Feb 2022 19:12:02 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1643847122; bh=Vcz3MlyheMLYNtks1bZep/m6+6iAU6tvsg3u01qbx3A=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject:Reply-To; b=fEAqM6OeJhr/JRqnBy2oT3mxfJ9x+b8TiNhuMvHIVGK+7H8a12T10hy8AiYwIRQuT5Rhkcli5D6AOxiYoUd3pDfsMTFUMjZ4wWTM2E7KGhnzOxxHMRIT8SxA0m1Nd0Pk2DnlitytZULJhu5WRxWvNLYIW5SllSIjyRnO4QCbJ3rdqIACq5mWeHKdl4TuNSUBa5+FZ8H2DNKp3NdJVwzimkm/FQCHXiEW4eRMH8zlIUGCQ1hEcZccOlMd/SDYtvKiEiYA10m9mKSj42oF/hmMtODMHuCq8Sg6wSayqfeOzVxJoE9zV3N0OnYqDXN4vJ1EvolNWr1qrEWaCPGeBiy+aw== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1643847122; bh=l1gqNJv+YoSrfGWfCp6/rMi0udAae4R0YlLjOCNO3Cd=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=d+1QWKJKiJwH+Hd2RjsahJaas93aa0AxosvWbr+QofXSoWfxaqetLkX7vMS8rjUmo91iSHF2Vzy4K92FUD+IC7R25joY5cuWmEa6yAZf7D5rsa6pEMRwOFUHnrT0JqhCEhObxXIISzUuDNjjj2bLmbHyAvB3QOdD9UOpUyXxBRf1DOIPVdH0/9qPhsdM5oNOB2fXT/ENgqL3s109dXuoFvDM+qcY007RmmKTNf5ltHNeHn6970vaOfNKWr2u8fegLMoA6tVRpMQc47uDaqGlWAhKFi34SD9eke2fybogE6DN38TD6ckpbsHG7S+m1fq8M6hCWptJRbhqHRLSSUML2g== X-YMail-OSG: ANiogCwVM1mn.v8mw_eCayAF0KHqCsjjQ5DDVwrzO_hwnj_GSsQKHDVjpEAz5AE ZeptoDBfgs4By7K455F6_sCVPrhXRLV3ZdGcJb9nIn7oXvVeX8rIjuoFX44M_xhR453_z3uE5EWp nq5UD8ayUAC1dku74kpaJ9Cfp5yIfURu7m3XsFpjh8aTIrbndeQIjX0S5EK7D._T.2oGWOYNTJcq dcMckxI2zqgYh770b_xkWEUctR_c3HPer9yT5kTZoiZZjwOIIol.afAD084WwAgw0ZP1_vHRkxGq 9fZ4SBYslanWeNq9aHJkSG8bMdigfKuKzP.t0HZg7FSIHlwFrMNrDuUe4Mq_svnhjfaduKcCKxt_ 6B_F3hc1suRdN_ns9GnBQfmcyLVU8jiYPFSZ2Cd7q_Mr0116wHMvDJRh47oxoGn.6b2TvhUSo.O7 fCWsEUL9Jn_Ib.la2x3TaVhd8ZR0KqNFZ0PGw68T5f6PjS.F9JmvwFY72Jtv48r_KYErauhY.rLM XayHm.6j0meP1FdQAsq5mElSx91eUKuY7CiO9cXn3xPnxS2334sxIBuMlh67vZk49HY11JsbivB5 rld7t3Leptg_EwBC94YbvfR8Jmbo..VGe5MDPnYkogXDC66RHdjqs09UHv1bENgnw126Q4mHle70 pjWYHaOeQ3L_RUDWyQcpFmxUGkcEOkx6YK_77V7Jo7ICCN6fbHsw9uCVr6z3.5MMhmmeUT2CvsHi 3uAviqx6tt1A3u4qHdkNYEc0QpQIqM5IfJJoWNTF7Twe1c5JkZ0BzIWeAdPsM_3MC5q0x_ufJ6s0 iQjZVML90IJfcDcRk6SDBPh3QxfpO7b_8KIoZdA4HEKQrHyH0HHLGdFsaivCxTNcwG3xUz0z5IVZ u_CsVLroFleMvjsFrHfj2Dl4U12Xl4nj0gVZ_Fl4FMpUqBncd4Mi.z_YK2vr95G82lhIerwM6OvY 62cROJ82miS0le8w0G5tpXZbsQnmfIWcvUWH_VKi5qHsAZ1DylWQJ1YNJs0aNfdXJB02XiS3sdbf KM2HM0CI0ABsRDcgvx6h6g54zY6Z9PVSGXBHWrgErBXyOkYhS2B4_QQBalB7TxF56oyGGr0HhaVY jGdKplXiosuj_9KuEfPpA6KWNUwsV.MOFn2wvKsMadATFVrVEVMpMSc.pQ6__Usi5UnxSa5NdnHb yQiM8qOLNzM9gp07bQ7Fw1.mVOKO52JLidJpGSkRzHN4.PkTyK9fsD5Eq7w9IRiiSwKuyRMCGr4O TVRUYV_IdiCuG3k72ueetrAk3JnMBSnkPM6iWsJELpRRwk.HmV0.xczNslCUyP9vtd7a__u2vPCN G78COo2q8W9JgTKaluF6R1OhLOc1uBJwauzbgVRwxTg7nj5HwkQG.8lGA7kXMSjPQ4uN0GH0pl.W GP.knKskAonsW8AMPGC8mGQDMKg8waUe1jb8KJ.6n2kXmNPa6gEeWueuvUNEww2x2mZKhYcTN9jd jNj2kIV61VbmEzgjihmdBYqyBoyOWeYDZFcIuQqqS6u6c4dS5PHnU4O7LVx0FGr9VpLXgGpdybLN Uj0Jhu9XTalcWMDtAwi5ytS8QlbODdmrhS760BXrBArWaj5XBT.XeaTYP7a5ycPBs3gUMd7uinWN 6Fmkg5VwHDqyEnZ9jUKQYCZwj4IU96.2fSfk8gT81hW.FOnYc393tywcrEanm9xnwl0TRmUkDuZK WwslDtRKsjgeAOfJwe6zy6KhH6c5Tspuhy.PeQixMUkOdn1OZf7Pmt0n80N3lEwgyi5UUIWB3Q0Z hu18wLqJ35pmrkVMLW0ru7ye4oPY.o15u8KR.vIVNki5.5lZeldxplDjOSf.x.dNklJvcuSlivSE gARkRobDIeJa.afq8WSv.irhJV.sCSPPfS1l5ASu51nTo6pH.x_sUv34Suz5Jhw8wtnAa.JJvxTp KnVywwzqGyRVaUQ1WE1VmwBTUZuJJMRh_KRTeJTVPshAADIfzKBAflBdVF0RBda8VAHBJ0r.PnYx HrLUxKs1uB4QZ_YF5c_7gvIR8_WBw4ZZgBQRZZb94vzzh2qrtrRZTmXzLs_kg6mN5jyqeYStLzHr RtQx4ay6jFQyHki9o_LDtYNnymbs4BVEkJFqVI.EBhgP5Go4gjjfQpXC5CMD72sB6y8ne62ToNwO QXgGefaCgG0IhljBikUg920iNDRBAoxGCXqW4eMkI_CQb_zu2Kx1RkCe4EbU.Dgd1HQDsv64u.EF lgrdahAyo1Iyk4QTUiXiPmLTsO1oOqSsQ5Rj5JpEkB1l0yHjboacoCMdQPlOJjD4Ui6MYixmBBOZ 1iQ-- X-Sonic-MF: Received: from sonic.gate.mail.ne1.yahoo.com by sonic311.consmr.mail.ne1.yahoo.com with HTTP; Thu, 3 Feb 2022 00:12:02 +0000 Received: by kubenode505.mail-prod1.omega.bf1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID 983446ae350fa35af88aaeb04f10d176; Thu, 03 Feb 2022 00:11:58 +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, sds@tycho.nsa.gov, linux-kernel@vger.kernel.org, netdev@vger.kernel.org, netfilter-devel@vger.kernel.org Subject: [PATCH v32 16/28] LSM: Use lsmcontext in security_secid_to_secctx Date: Wed, 2 Feb 2022 15:53:11 -0800 Message-Id: <20220202235323.23929-17-casey@schaufler-ca.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20220202235323.23929-1-casey@schaufler-ca.com> References: <20220202235323.23929-1-casey@schaufler-ca.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@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 72da145c1aad..79554e5adb4c 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -596,7 +596,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); @@ -1450,7 +1450,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 5aa2ee06c9e4..03824cca058c 100644 --- a/kernel/audit.c +++ b/kernel/audit.c @@ -1188,9 +1188,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) @@ -1438,33 +1435,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; @@ -2147,17 +2144,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) @@ -2165,9 +2160,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 1626d8aabe83..7858da40a767 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="); @@ -1353,7 +1350,6 @@ static void audit_log_fcaps(struct audit_buffer *ab, struct audit_names *name) static void show_special(struct audit_context *context, int *call_panic) { - struct lsmcontext lsmcxt; struct audit_buffer *ab; int i; @@ -1378,17 +1374,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); } } @@ -1543,20 +1537,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 212e12b53adb..9626e2b0ef12 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -339,8 +339,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; @@ -348,7 +347,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; @@ -357,13 +356,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; } @@ -656,15 +654,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 d986bae1587b..625cd787ffc1 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 163cf0ae2429..d56fcb794ff4 100644 --- a/security/security.c +++ b/security/security.c @@ -2330,18 +2330,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 Wed Feb 2 23:53:13 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 12733612 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A226DC4332F for ; Thu, 3 Feb 2022 00:14:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1348375AbiBCAOP (ORCPT ); Wed, 2 Feb 2022 19:14:15 -0500 Received: from sonic317-39.consmr.mail.ne1.yahoo.com ([66.163.184.50]:45974 "EHLO sonic317-39.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233665AbiBCAOO (ORCPT ); Wed, 2 Feb 2022 19:14:14 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1643847254; bh=OPmcc6RxdekExVViioUe9rMhP6xIsP6mDCh0RBi/+Qs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject:Reply-To; b=h8ffBTPMoJFah9n8Qm3CDl+XbQlVrT8q5syZItmtyN9hlRKqoT+Ft3pWI7Ip3Tvw29hnjwoe4lnrA3SG3iL7NHNfnFPPhDtzlv4HdA1NilUmRfpyHMkebIFdSS+aTq3dANiyPsWKBHxG5atXI6qpi4w5ofBoLUs45oHfNguS+ttLHzbN8dg4/MMzd5zmvye23HFGf1XuivJdREpa/UMYqzRRp13IXFWoOva6ckrW0847SI6LGR1cG+oFbcPi+GfsL3U7xWEOTgYhj2TChFAbtceTgzfjldpOt2gOevqf3o1lQL2P5nPbDplORDaHRJrY0iZiXaRN3iW9zMftB2ULvw== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1643847254; bh=JWLmen0v1iaGlr+fMYDNSNw6J81iTVeWtMd+lDm0dp1=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=TCC7t3uvlVUcJOtc4rr3X2vGyYaihwytEuMAHvyoqj/gboDkj+yPKA1mBYyPhPJ5/VYEV+L6AUu/s4D6nAm93L/guduUYY/Y8KIb+jxznKFsTbSdsb7i3IDnD2LHVeG+8Mtz3+O5sYTXaUBegXW90y7dcdBa/enHCw1y8NFjYVzZJeevwlqS25abvMqJi0IIL7BykJeXLhdlyNzpkKor42wdR7jD4RLBx7yWKQlBNO94cfUaxdAF+gxBulin/ZA/PXarTxwboUVWNqL+PRRNtPjzFH6bQA8dAC2tbVZ3e4fO0fYVn/PyLnSff69vLRwVKMJcU4doA8fZ3zO8rRoZIg== X-YMail-OSG: qosHQDwVM1nikMe.7SO6m5ncuiKLq9iyb4U_sxQnVywwIUTg9s9QO9r3LUQnwH7 aDGbdAHz4USz5O3roJ_uy.70DLhLLasHmaUz1C9bxDRhKVaFFzvV4Bw0.X3EbmPoRrrSQ.r1vAW6 aj3c9sejtoK0KfvByyqMomQOwAe23XzYZ74UuCfAEKXKgmwiQIdcNRNQACblPX7x5CwNMqsJBA73 idy4M9MMLHdPoWcxgvAqGZ2pDjonrN9WR7rOsqXyzO_HNI4xCZJ72sk7MoslCwAk3.D6b52MzTEs jnmnhBT.gxBVeEd.GsZu2fHzNUlIQUGxKUDKlzO29wbsvvDht.TMW9qf9qPnalWcMIyOQo1CDTdN P9M4qcJ8fR7XTk1kGYAYF2GrYZ3MMrxp7NLuse44J1tJLJTSYQLnFtrsi4V_IVqnabbqcXWIQCaM JtU_K8xxALIfnhZrWutIX7TSzBVtxkchRq98MlLj_N0GCxHbFLtVWfOBGqxnUCxU4UQ0o0rcTHmg Mhgy501Vc5QaigA68jNaeZBGgqpz9QXPWSeniiuGAm62bmD2RCvDKp78Wn8PRCxxNqz9HJWFk.Zs 5wBMxubGu4nOJ6AQCFIXaEbxZ_wk3MQ2ewW6uJdd3uv_OxHPiyJNtkbkX4MxhVqQeZ8SBea94yIs THXQfS.9zWNF4l4KUME2SYQm.8h9boHyZpZj5tZlRCVV8Ya3MQbRLHC.Jg9p593WgvekFTw0BTx0 rj4SPrXqvdyWHaUC3u.Lrm.kV0pU7wPnPuIzIKhV03wEaFfn59Evxe0DgD98eQcoFPssBpChP.M5 Ne9uQzSN31l5gNEWO4LNF8D73gDst_31l0QbMf.gwOI89Qjv1Y4Gf2SWfvul7sMD8dsWfMWH53R9 3pm50utRysavJ6S8ZWFRXOVGW9aTeWjrv_X5xEEfR_F4X_NXKOfHoPsAtgJWPapNqwFViAJdf_rw WEF09weCRWjDj3OTYx87Q3a6tXYMtd8VEdQTDnZCs4CXGQh6cVTtj9VOGzLsLxZD.gRmYfQAf1qO KvTdvDeV3QEDKW7cL3pfKrrHSXh4xb8oWg2wOWDvEjlD3UdrRxH7elcXL8REq9_N8mCFKZOjd8nv 8MGsA4ghmnbnSCHRhyZRHi8mYw14jF_Eir9BgOVgcRE1wBKuQuveXIuT0dgH_GmnP3cO5uOuztIT HCS9fpzVtnqmtTvt1wn5e8zS3XnPdzULFujL2nzR0CQsNgHPNaABtXdXgJfcOLy3ni4.Cf21TbQJ xPrVCbwwtzVJUTD1rQQiH6nWrGGasRSgIa5tYAVyVbTfQqoh_2QsLTlo9YkWaA3HoRNKvU5MXiSO ADkH24wZGcOX7viG03JDrTis7pDdEgu9FzvjeN28JhVI8pPDUioZvJaskPYHldO9hKXiDulyl_xO akvApLx4UHSKdMNItUZ0eb6AuQdy1_P51Vhi4NrbVxVDpPOB8tPYj8QlVVYj_UuvAL0.GvYmVXEl xg86A2nGc65alT04BURVI_2GOAsP_paM1eseUXDJ_031GA2WvhGNQrouCkokXDcXDharTG2RAD6n C_LrCmW.Z68HmrReEh0VXi6t0kaBZ66TlMIie2IPjFwD0rTnXG5brd0MzTKuScGWj63sKoPQr8Gm y2mByFfB7LbIaBL2P5unH1g_OsjGqRavwaOqZzyGszPZ7YpqWH9QGsZjuHR8NbysW6KmPiW6iqi1 0i0Xu4VbXj2RH4yPZMWpKyNZFaFgFjDHnIQ.41bx4SLIfIzZiTsi.BQ_zpjN5foA6d_6dPhUgRhZ Wew1p0VxwfFya9iEIe.WRkAo47_6Znv16DP4M8hzPn.8ZD9C4e0akt1GMfBN2jeuQmzNymeYMNqd 4Io_BFeMWO7WOrOeJpBSradF95J1mJSLcc2n6H69BLZSF3JISMrp5yVGvABje03JqAiAJU5nKUYN b_Zl5bWQbiD5x6MCYpchmMWw8_MWxuxkci57hCAp0NpcOCUHZeTNJNJfdGRTwdikrk87ighHz.cq CSvkIiJpZpjbd4DBqXBlXuB7UnYEHC_x37MivQeybXPyPHaHAJnN2g8eYJn8VVH0pbWScSH5.hGd 50bmm5C3xfHVIc0imJnIp.CWnbCSVoLQKvnl6X_za3X.vIpnZy8xNX8Vr4jh2goZJpbzwQi7piW_ SXnWWYhJijl4F3_pMZcic4ryk9br8S3aTFqJIczvrs2IdAQE_4BAJcXdqAOdJ6lbMSnST3a7.yaw fDu2NUvV4wpcInIPCuC.3zdp7bOmJRSMdbU3Ur.NOT_ygqsWZH2RwobwBSLj3aw1bWXPYZVQhPrK d X-Sonic-MF: Received: from sonic.gate.mail.ne1.yahoo.com by sonic317.consmr.mail.ne1.yahoo.com with HTTP; Thu, 3 Feb 2022 00:14:14 +0000 Received: by kubenode514.mail-prod1.omega.bf1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID a29bd64dc2f4fffffe40b3652cb32a1f; Thu, 03 Feb 2022 00:14:11 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, jmorris@namei.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org Cc: casey@schaufler-ca.com, linux-audit@redhat.com, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, paul@paul-moore.com, sds@tycho.nsa.gov, linux-kernel@vger.kernel.org, Stephen Smalley , Pablo Neira Ayuso , netdev@vger.kernel.org, netfilter-devel@vger.kernel.org Subject: [PATCH v32 18/28] LSM: security_secid_to_secctx in netlink netfilter Date: Wed, 2 Feb 2022 15:53:13 -0800 Message-Id: <20220202235323.23929-19-casey@schaufler-ca.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20220202235323.23929-1-casey@schaufler-ca.com> References: <20220202235323.23929-1-casey@schaufler-ca.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@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 625cd787ffc1..2aff40578045 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; size = nlmsg_total_size(sizeof(struct nfgenmsg)) + nla_total_size(sizeof(struct nfqnl_msg_packet_hdr)) @@ -470,9 +464,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); @@ -603,7 +597,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) @@ -631,10 +626,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: @@ -642,10 +635,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; } From patchwork Wed Feb 2 23:53:14 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 12733613 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B6591C433F5 for ; Thu, 3 Feb 2022 00:15:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S245692AbiBCAPU (ORCPT ); Wed, 2 Feb 2022 19:15:20 -0500 Received: from sonic314-27.consmr.mail.ne1.yahoo.com ([66.163.189.153]:41918 "EHLO sonic314-27.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1348418AbiBCAPU (ORCPT ); Wed, 2 Feb 2022 19:15:20 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1643847319; bh=qvgUu0vofJzjZUietoxZexLdMa3YX3sit8IIoQiY16Q=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject:Reply-To; b=V3K0bapdXwsfo/RN1ur8kIHJnRmEU1HkpNWgLljIPhC4i6vwleycSI8iF2S+bie67Co6N4JSS9rdEd1R5EoJayKYwOlXFYZzhraRzUNXqUjalTpsgr46KOo7TuY9pty0MmH7y6Ygz3d9RDJH+riVmi84e3QdVUvq61ObSjmb0cSvxmIdr7XSh8KRw/Cb8d5VtIJ59EyLaG2L4r5xqq1CqLpG6VLR4HwnYV8f5mLZ7UdKAD7pY6lq1O/c+sy0NTVHNbgv9GE2r6De561Z6CnBVNBzQuJXErNHlxulAM3nJUbpk4q6c2S/VE8UXjNDeb+Z5ZY8rxeEBzni0VSzJsHU/Q== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1643847319; bh=RDi9+Mu2CoZl801wDGOiIeOmLCpJM9QuxRIVIige4qS=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=njlrYqHguX9zFNsZWyHe3nMCP70Y/0h1R/JrdOuEp75JUXrhMgtWbAc/+uBQoWZkqhOp9LrQdlDuO2tgZ9DGXx3PbByKxjBHaBHmPAE87U7rIuYTYnw6ySiNisnVP+2BbSH/34rZuBtiFMFEvSu8u+FKdWo7XH/BoYhtWkSXvCYevFuZbmbN7dkE9zB4w9gW9yFHKjbwB4m2c07mBbANSn02dp1RaVw/+cHLLMtmF9JQyMBTPLF07Xg9SXute/J1Pz41zyw1khev1VPwdtuMcvwpchk9cXTTibytHm85AFUA1DfnBPusaaclnDpRs7bLeUtq0F9W6P0Ay5g9uMq76Q== X-YMail-OSG: DLkA9gcVM1klntvvI0IPfylZh6x6pCq2aa7orfhX14HCjDsaEsuSXLj2sZ9Fp0J H9kiPB5nkSE3HPj_vVEnKSvqPuScpUsSDur8SHfVsExIGHBk_rr.m60JlWZRH9tLd.5TYuew2M.s cI.aNixBRphhvy8npaK6pTvn2dfiVL6LlwnKbw_HKyhNb5LjCamX6i7jUR33RZw0N64MI40VlloE 7_XfeCnwM38oeR9omJv0mDH6HU2Xuv0OGoxSr_fL2RCTbaX77KMqCBz25X_68NITHluLnR06I08w GpRwVqLq6IxwOronursgzVaEjmSxlejw4yRAtirXMnKJF5uVEYwxkdRK.YVsQd65rdr8zI4lPZCx kbn_scDs78xSl9XQxRn1CiY1oemzbkChuhaObRnxplCIzpNopzR3SISt8v8WaNb4HFliZSWnwG7A tcj7DheZPxLoRxJJVnUNfmJXt2Xgr5GT8oG8MJtlfp39jV8v_Zeoi9dzYovH0VsfRjG2RrPbqYxe thdhDFp.8xko18Bmik3D1qtIWOBycCilh9KHPOWvku5iBXAL7hyj7avTNOr8wjB7rbxeSPF.saYG IphGU5bh7oZocFjOoaldMZ2ToQr5X9m2veWgHBach0AECKriO7.xeyJ6jutGLhR8Xg2yhF3re2Yd VAU_Sh02FAO6ykkoEYTA07Nu2Cax5TseOjwZyMsZeMDZ6gxs4GsA0cpHlQenHGgK.1cmOygkJcug Uf7LnC2ghMBmJxiDKKzYgkSsp5xwxJUpB2pGiUSbvPSG6LT.bmedzuMU_r7fAzNOkZTVTeMBE2kI tUbWwbqmEHjOG2kVFKl9lZOZPGcAK63KKQ9tay4xc1iA4ntaFBdpcRJHbx.C3l0oukG8icP1kxNL 5TGMyb3_P8gH5Iij0hirisJ9Nk0igABf747Mhg.1RDppxW9HB3YD3_LktCA19y_TScodr6n_Ye0P odyjo6A0d8tm8m5HcqdnwIciB8ysjaUFBAYZ5h9D7tHsvGUexEYCvhAo5fpti9XJ6TmNQS9zrJtw IAiBkys4gk1df6zdAc9SKndsJzvgB9vsRzuo3p87pkTMoDv_SiQytMfDfQPBFk1AbV.xRYFvxi1U 8nuRrkhkFNUKizeWvYlJlxSlU83C5zs2Q5Ap35GQlmxUuHhX28xPsaPrL4BiEm6uvDRi2svvXxpl .5ubh1nGRyOCb4OlLxCNh.kzrSoXeUY_.Gd.mdsmU1xD6XLrzdYj0eS_AusIpFn0oITYr3NNNFlV msKwtOFf1vpjQX7Fptb5eiz7uDqYT2lwSYSWd66hYiGHtWOdlByaUV0muTJajEVepLY7sfaS7nXp e4XmQz6LZx0ir2DrsvKW4IfgLt.QeHyocfX89fAnMvyTTB2dRYhbhNsTzNy90xGCjeWWHJZrTyN_ QKY0PPFnC3way3TxbEngurV4PFdUSTmJqhhQad_nA0gcYtERC1YdaCVPP7M0lkZ_rsp_DnXNIc1n b3FRGrL6Eui6Nqh8yYcbV8RyjO.Cl1g1QWrZWBtOtb66GFMaA42HywM0Fk7eMMlceIjQd.c5o5Gb qRmF.0nopnbEreBj.djUbDFggrAW.sUEnv5PwWPKOuuatICc0gck_rPKGeOJfAVkO9vXWX89fvgN s6DladdlUyqOCEMx2wpL8mXqhkgwtZdfPc3sAORFuYumheDHbzYmP2s81clbNmiqGjfX5Sb2vnkp U1hHdcgJd_YTjPZNrAe0r5lG_N0XbAGp8oIrtWflCD_ZwccMXFto6Z7Ep_nhE37tQ4Tw6etLcC.Z X48hEM2s1MV2JQK4gAHbZP6oRwDQiGlNB30Iqtr_2nmx9MOBGIH2k80M1SoELTyEmEL7jO3573a1 rPvNqTBIdINGG55TqLXYnmb_Rp8cX9JvrxRQMgXoOAv4i6EnRWrglU.1psKW_EV01xKQI1hRkuXa RTLU8Ai4p4L2kSc2h7HBGJChyQNUryE6oT8G4E_4XWJdpVfXjrqORz1nSv5iEzKmhk5m.yfyWsfb g_tjt70QEJF.YVx1vURgQDcKbHZRb.0z5lfynYEI_2jB1jKHdKOFhUGAzA0GxO7H5lRV_HMC6_tz gxjx2qPTi2ZTmH_RFcyWCA52I96qk69TQPjzhQme5qxXPKkGOtgkLCdXyiAwuVgJDhhZ_yyvnn9K QBZ5fNr5xEf_PHkvKCvHTzJHhsE1HO.0R.c88.lpcEdLKcDmHaAvmoyf.GdAe7KRdnyCn7FKxJnF v.bit2vROaanBtuy5kHpuVvIEOXo6yx6d1S35.VEmYiioXdpwhfk. X-Sonic-MF: Received: from sonic.gate.mail.ne1.yahoo.com by sonic314.consmr.mail.ne1.yahoo.com with HTTP; Thu, 3 Feb 2022 00:15:19 +0000 Received: by kubenode518.mail-prod1.omega.ne1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID 0d0bcbdd7bfb25bb2a79335f410dc581; Thu, 03 Feb 2022 00:15:17 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, jmorris@namei.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org Cc: casey@schaufler-ca.com, linux-audit@redhat.com, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, paul@paul-moore.com, sds@tycho.nsa.gov, linux-kernel@vger.kernel.org, Stephen Smalley , netdev@vger.kernel.org Subject: [PATCH v32 19/28] NET: Store LSM netlabel data in a lsmblob Date: Wed, 2 Feb 2022 15:53:14 -0800 Message-Id: <20220202235323.23929-20-casey@schaufler-ca.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20220202235323.23929-1-casey@schaufler-ca.com> References: <20220202235323.23929-1-casey@schaufler-ca.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org Netlabel uses LSM interfaces requiring an lsmblob and the internal storage is used to pass information between these interfaces, so change the internal data from a secid to a lsmblob. Update the netlabel interfaces and their callers to accommodate the change. This requires that the modules using netlabel use the lsm_id.slot to access the correct secid when using netlabel. Reviewed-by: Kees Cook Reviewed-by: John Johansen Acked-by: Stephen Smalley Acked-by: Paul Moore Signed-off-by: Casey Schaufler Cc: netdev@vger.kernel.org --- include/net/netlabel.h | 8 +-- net/ipv4/cipso_ipv4.c | 26 ++++++---- net/netlabel/netlabel_kapi.c | 6 +-- net/netlabel/netlabel_unlabeled.c | 79 +++++++++-------------------- net/netlabel/netlabel_unlabeled.h | 2 +- security/selinux/hooks.c | 2 +- security/selinux/include/security.h | 1 + security/selinux/netlabel.c | 2 +- security/selinux/ss/services.c | 4 +- security/smack/smack.h | 1 + security/smack/smack_access.c | 2 +- security/smack/smack_lsm.c | 11 ++-- security/smack/smackfs.c | 10 ++-- 13 files changed, 68 insertions(+), 86 deletions(-) diff --git a/include/net/netlabel.h b/include/net/netlabel.h index 43ae50337685..73fc25b4042b 100644 --- a/include/net/netlabel.h +++ b/include/net/netlabel.h @@ -166,7 +166,7 @@ struct netlbl_lsm_catmap { * @attr.mls: MLS sensitivity label * @attr.mls.cat: MLS category bitmap * @attr.mls.lvl: MLS sensitivity level - * @attr.secid: LSM specific secid token + * @attr.lsmblob: LSM specific data * * Description: * This structure is used to pass security attributes between NetLabel and the @@ -201,7 +201,7 @@ struct netlbl_lsm_secattr { struct netlbl_lsm_catmap *cat; u32 lvl; } mls; - u32 secid; + struct lsmblob lsmblob; } attr; }; @@ -415,7 +415,7 @@ int netlbl_cfg_unlbl_static_add(struct net *net, const void *addr, const void *mask, u16 family, - u32 secid, + struct lsmblob *lsmblob, struct netlbl_audit *audit_info); int netlbl_cfg_unlbl_static_del(struct net *net, const char *dev_name, @@ -523,7 +523,7 @@ static inline int netlbl_cfg_unlbl_static_add(struct net *net, const void *addr, const void *mask, u16 family, - u32 secid, + struct lsmblob *lsmblob, struct netlbl_audit *audit_info) { return -ENOSYS; diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c index 62d5f99760aa..bb9c900da6b0 100644 --- a/net/ipv4/cipso_ipv4.c +++ b/net/ipv4/cipso_ipv4.c @@ -106,15 +106,17 @@ int cipso_v4_rbm_strictvalid = 1; /* Base length of the local tag (non-standard tag). * Tag definition (may change between kernel versions) * - * 0 8 16 24 32 - * +----------+----------+----------+----------+ - * | 10000000 | 00000110 | 32-bit secid value | - * +----------+----------+----------+----------+ - * | in (host byte order)| - * +----------+----------+ - * + * 0 8 16 16 + sizeof(struct lsmblob) + * +----------+----------+---------------------+ + * | 10000000 | 00000110 | LSM blob data | + * +----------+----------+---------------------+ + * + * All secid and flag fields are in host byte order. + * The lsmblob structure size varies depending on which + * Linux security modules are built in the kernel. + * The data is opaque. */ -#define CIPSO_V4_TAG_LOC_BLEN 6 +#define CIPSO_V4_TAG_LOC_BLEN (2 + sizeof(struct lsmblob)) /* * Helper Functions @@ -1460,7 +1462,11 @@ static int cipso_v4_gentag_loc(const struct cipso_v4_doi *doi_def, buffer[0] = CIPSO_V4_TAG_LOCAL; buffer[1] = CIPSO_V4_TAG_LOC_BLEN; - *(u32 *)&buffer[2] = secattr->attr.secid; + /* Ensure that there is sufficient space in the CIPSO header + * for the LSM data. */ + BUILD_BUG_ON(CIPSO_V4_TAG_LOC_BLEN > CIPSO_V4_OPT_LEN_MAX); + memcpy(&buffer[2], &secattr->attr.lsmblob, + sizeof(secattr->attr.lsmblob)); return CIPSO_V4_TAG_LOC_BLEN; } @@ -1480,7 +1486,7 @@ static int cipso_v4_parsetag_loc(const struct cipso_v4_doi *doi_def, const unsigned char *tag, struct netlbl_lsm_secattr *secattr) { - secattr->attr.secid = *(u32 *)&tag[2]; + memcpy(&secattr->attr.lsmblob, &tag[2], sizeof(secattr->attr.lsmblob)); secattr->flags |= NETLBL_SECATTR_SECID; return 0; diff --git a/net/netlabel/netlabel_kapi.c b/net/netlabel/netlabel_kapi.c index beb0e573266d..158bab993e32 100644 --- a/net/netlabel/netlabel_kapi.c +++ b/net/netlabel/netlabel_kapi.c @@ -196,7 +196,7 @@ int netlbl_cfg_unlbl_map_add(const char *domain, * @addr: IP address in network byte order (struct in[6]_addr) * @mask: address mask in network byte order (struct in[6]_addr) * @family: address family - * @secid: LSM secid value for the entry + * @lsmblob: LSM data value for the entry * @audit_info: NetLabel audit information * * Description: @@ -210,7 +210,7 @@ int netlbl_cfg_unlbl_static_add(struct net *net, const void *addr, const void *mask, u16 family, - u32 secid, + struct lsmblob *lsmblob, struct netlbl_audit *audit_info) { u32 addr_len; @@ -230,7 +230,7 @@ int netlbl_cfg_unlbl_static_add(struct net *net, return netlbl_unlhsh_add(net, dev_name, addr, mask, addr_len, - secid, audit_info); + lsmblob, audit_info); } /** diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c index 46706889a6f7..3aab71ba3841 100644 --- a/net/netlabel/netlabel_unlabeled.c +++ b/net/netlabel/netlabel_unlabeled.c @@ -66,7 +66,7 @@ struct netlbl_unlhsh_tbl { #define netlbl_unlhsh_addr4_entry(iter) \ container_of(iter, struct netlbl_unlhsh_addr4, list) struct netlbl_unlhsh_addr4 { - u32 secid; + struct lsmblob lsmblob; struct netlbl_af4list list; struct rcu_head rcu; @@ -74,7 +74,7 @@ struct netlbl_unlhsh_addr4 { #define netlbl_unlhsh_addr6_entry(iter) \ container_of(iter, struct netlbl_unlhsh_addr6, list) struct netlbl_unlhsh_addr6 { - u32 secid; + struct lsmblob lsmblob; struct netlbl_af6list list; struct rcu_head rcu; @@ -220,7 +220,7 @@ static struct netlbl_unlhsh_iface *netlbl_unlhsh_search_iface(int ifindex) * @iface: the associated interface entry * @addr: IPv4 address in network byte order * @mask: IPv4 address mask in network byte order - * @secid: LSM secid value for entry + * @lsmblob: LSM data value for entry * * Description: * Add a new address entry into the unlabeled connection hash table using the @@ -231,7 +231,7 @@ static struct netlbl_unlhsh_iface *netlbl_unlhsh_search_iface(int ifindex) static int netlbl_unlhsh_add_addr4(struct netlbl_unlhsh_iface *iface, const struct in_addr *addr, const struct in_addr *mask, - u32 secid) + struct lsmblob *lsmblob) { int ret_val; struct netlbl_unlhsh_addr4 *entry; @@ -243,7 +243,7 @@ static int netlbl_unlhsh_add_addr4(struct netlbl_unlhsh_iface *iface, entry->list.addr = addr->s_addr & mask->s_addr; entry->list.mask = mask->s_addr; entry->list.valid = 1; - entry->secid = secid; + entry->lsmblob = *lsmblob; spin_lock(&netlbl_unlhsh_lock); ret_val = netlbl_af4list_add(&entry->list, &iface->addr4_list); @@ -260,7 +260,7 @@ static int netlbl_unlhsh_add_addr4(struct netlbl_unlhsh_iface *iface, * @iface: the associated interface entry * @addr: IPv6 address in network byte order * @mask: IPv6 address mask in network byte order - * @secid: LSM secid value for entry + * @lsmblob: LSM data value for entry * * Description: * Add a new address entry into the unlabeled connection hash table using the @@ -271,7 +271,7 @@ static int netlbl_unlhsh_add_addr4(struct netlbl_unlhsh_iface *iface, static int netlbl_unlhsh_add_addr6(struct netlbl_unlhsh_iface *iface, const struct in6_addr *addr, const struct in6_addr *mask, - u32 secid) + struct lsmblob *lsmblob) { int ret_val; struct netlbl_unlhsh_addr6 *entry; @@ -287,7 +287,7 @@ static int netlbl_unlhsh_add_addr6(struct netlbl_unlhsh_iface *iface, entry->list.addr.s6_addr32[3] &= mask->s6_addr32[3]; entry->list.mask = *mask; entry->list.valid = 1; - entry->secid = secid; + entry->lsmblob = *lsmblob; spin_lock(&netlbl_unlhsh_lock); ret_val = netlbl_af6list_add(&entry->list, &iface->addr6_list); @@ -366,7 +366,7 @@ int netlbl_unlhsh_add(struct net *net, const void *addr, const void *mask, u32 addr_len, - u32 secid, + struct lsmblob *lsmblob, struct netlbl_audit *audit_info) { int ret_val; @@ -375,7 +375,6 @@ int netlbl_unlhsh_add(struct net *net, struct netlbl_unlhsh_iface *iface; struct audit_buffer *audit_buf = NULL; struct lsmcontext context; - struct lsmblob blob; if (addr_len != sizeof(struct in_addr) && addr_len != sizeof(struct in6_addr)) @@ -408,7 +407,7 @@ int netlbl_unlhsh_add(struct net *net, const struct in_addr *addr4 = addr; const struct in_addr *mask4 = mask; - ret_val = netlbl_unlhsh_add_addr4(iface, addr4, mask4, secid); + ret_val = netlbl_unlhsh_add_addr4(iface, addr4, mask4, lsmblob); if (audit_buf != NULL) netlbl_af4list_audit_addr(audit_buf, 1, dev_name, @@ -421,7 +420,7 @@ int netlbl_unlhsh_add(struct net *net, const struct in6_addr *addr6 = addr; const struct in6_addr *mask6 = mask; - ret_val = netlbl_unlhsh_add_addr6(iface, addr6, mask6, secid); + ret_val = netlbl_unlhsh_add_addr6(iface, addr6, mask6, lsmblob); if (audit_buf != NULL) netlbl_af6list_audit_addr(audit_buf, 1, dev_name, @@ -438,11 +437,7 @@ int netlbl_unlhsh_add(struct net *net, unlhsh_add_return: rcu_read_unlock(); if (audit_buf != NULL) { - /* 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, &context) == 0) { + if (security_secid_to_secctx(lsmblob, &context) == 0) { audit_log_format(audit_buf, " sec_obj=%s", context.context); security_release_secctx(&context); @@ -477,7 +472,6 @@ static int netlbl_unlhsh_remove_addr4(struct net *net, struct audit_buffer *audit_buf; struct net_device *dev; struct lsmcontext context; - struct lsmblob blob; spin_lock(&netlbl_unlhsh_lock); list_entry = netlbl_af4list_remove(addr->s_addr, mask->s_addr, @@ -496,13 +490,8 @@ 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(&blob, &context) == 0) { + security_secid_to_secctx(&entry->lsmblob, &context) == 0) { audit_log_format(audit_buf, " sec_obj=%s", context.context); security_release_secctx(&context); @@ -543,7 +532,6 @@ static int netlbl_unlhsh_remove_addr6(struct net *net, struct audit_buffer *audit_buf; struct net_device *dev; struct lsmcontext context; - struct lsmblob blob; spin_lock(&netlbl_unlhsh_lock); list_entry = netlbl_af6list_remove(addr, mask, &iface->addr6_list); @@ -561,13 +549,8 @@ 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(&blob, &context) == 0) { + security_secid_to_secctx(&entry->lsmblob, &context) == 0) { audit_log_format(audit_buf, " sec_obj=%s", context.context); security_release_secctx(&context); @@ -921,14 +904,8 @@ static int netlbl_unlabel_staticadd(struct sk_buff *skb, 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, - lsmblob_value(&blob), &audit_info); + return netlbl_unlhsh_add(&init_net, dev_name, addr, mask, addr_len, + &blob, &audit_info); } /** @@ -975,11 +952,8 @@ static int netlbl_unlabel_staticadddef(struct sk_buff *skb, 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, - lsmblob_value(&blob), &audit_info); + return netlbl_unlhsh_add(&init_net, NULL, addr, mask, addr_len, &blob, + &audit_info); } /** @@ -1091,8 +1065,7 @@ static int netlbl_unlabel_staticlist_gen(u32 cmd, struct net_device *dev; struct lsmcontext context; void *data; - u32 secid; - struct lsmblob blob; + struct lsmblob *lsmb; data = genlmsg_put(cb_arg->skb, NETLINK_CB(cb_arg->nl_cb->skb).portid, cb_arg->seq, &netlbl_unlabel_gnl_family, @@ -1130,7 +1103,7 @@ static int netlbl_unlabel_staticlist_gen(u32 cmd, if (ret_val != 0) goto list_cb_failure; - secid = addr4->secid; + lsmb = (struct lsmblob *)&addr4->lsmblob; } else { ret_val = nla_put_in6_addr(cb_arg->skb, NLBL_UNLABEL_A_IPV6ADDR, @@ -1144,14 +1117,10 @@ static int netlbl_unlabel_staticlist_gen(u32 cmd, if (ret_val != 0) goto list_cb_failure; - secid = addr6->secid; + lsmb = (struct lsmblob *)&addr6->lsmblob; } - /* lsmblob_init() 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, &context); + ret_val = security_secid_to_secctx(lsmb, &context); if (ret_val != 0) goto list_cb_failure; ret_val = nla_put(cb_arg->skb, @@ -1510,7 +1479,7 @@ int netlbl_unlabel_getattr(const struct sk_buff *skb, &iface->addr4_list); if (addr4 == NULL) goto unlabel_getattr_nolabel; - secattr->attr.secid = netlbl_unlhsh_addr4_entry(addr4)->secid; + secattr->attr.lsmblob = netlbl_unlhsh_addr4_entry(addr4)->lsmblob; break; } #if IS_ENABLED(CONFIG_IPV6) @@ -1523,7 +1492,7 @@ int netlbl_unlabel_getattr(const struct sk_buff *skb, &iface->addr6_list); if (addr6 == NULL) goto unlabel_getattr_nolabel; - secattr->attr.secid = netlbl_unlhsh_addr6_entry(addr6)->secid; + secattr->attr.lsmblob = netlbl_unlhsh_addr6_entry(addr6)->lsmblob; break; } #endif /* IPv6 */ diff --git a/net/netlabel/netlabel_unlabeled.h b/net/netlabel/netlabel_unlabeled.h index 058e3a285d56..168920780994 100644 --- a/net/netlabel/netlabel_unlabeled.h +++ b/net/netlabel/netlabel_unlabeled.h @@ -211,7 +211,7 @@ int netlbl_unlhsh_add(struct net *net, const void *addr, const void *mask, u32 addr_len, - u32 secid, + struct lsmblob *lsmblob, struct netlbl_audit *audit_info); int netlbl_unlhsh_remove(struct net *net, const char *dev_name, diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 3469ffe195e6..7b9cb4d263c0 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -7020,7 +7020,7 @@ static int selinux_uring_sqpoll(void) } #endif /* CONFIG_IO_URING */ -static struct lsm_id selinux_lsmid __lsm_ro_after_init = { +struct lsm_id selinux_lsmid __lsm_ro_after_init = { .lsm = "selinux", .slot = LSMBLOB_NEEDED }; diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h index ac0ece01305a..9f856f2cd277 100644 --- a/security/selinux/include/security.h +++ b/security/selinux/include/security.h @@ -73,6 +73,7 @@ struct netlbl_lsm_secattr; extern int selinux_enabled_boot; +extern struct lsm_id selinux_lsmid; /* * type_datum properties diff --git a/security/selinux/netlabel.c b/security/selinux/netlabel.c index 800ab4b4239e..0b8f99703462 100644 --- a/security/selinux/netlabel.c +++ b/security/selinux/netlabel.c @@ -109,7 +109,7 @@ static struct netlbl_lsm_secattr *selinux_netlbl_sock_getattr( return NULL; if ((secattr->flags & NETLBL_SECATTR_SECID) && - (secattr->attr.secid == sid)) + (secattr->attr.lsmblob.secid[selinux_lsmid.slot] == sid)) return secattr; return NULL; diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index 8e92af7dd284..23a45c9dcf04 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c @@ -3899,7 +3899,7 @@ int security_netlbl_secattr_to_sid(struct selinux_state *state, if (secattr->flags & NETLBL_SECATTR_CACHE) *sid = *(u32 *)secattr->cache->data; else if (secattr->flags & NETLBL_SECATTR_SECID) - *sid = secattr->attr.secid; + *sid = secattr->attr.lsmblob.secid[selinux_lsmid.slot]; else if (secattr->flags & NETLBL_SECATTR_MLS_LVL) { rc = -EIDRM; ctx = sidtab_search(sidtab, SECINITSID_NETMSG); @@ -3977,7 +3977,7 @@ int security_netlbl_sid_to_secattr(struct selinux_state *state, if (secattr->domain == NULL) goto out; - secattr->attr.secid = sid; + secattr->attr.lsmblob.secid[selinux_lsmid.slot] = sid; secattr->flags |= NETLBL_SECATTR_DOMAIN_CPY | NETLBL_SECATTR_SECID; mls_export_netlbl_lvl(policydb, ctx, secattr); rc = mls_export_netlbl_cat(policydb, ctx, secattr); diff --git a/security/smack/smack.h b/security/smack/smack.h index ef9d0b7b1954..ac79313ea95d 100644 --- a/security/smack/smack.h +++ b/security/smack/smack.h @@ -303,6 +303,7 @@ int smack_populate_secattr(struct smack_known *skp); * Shared data. */ extern int smack_enabled __initdata; +extern struct lsm_id smack_lsmid; extern int smack_cipso_direct; extern int smack_cipso_mapped; extern struct smack_known *smack_net_ambient; diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c index d2186e2757be..c6dcafe18912 100644 --- a/security/smack/smack_access.c +++ b/security/smack/smack_access.c @@ -524,7 +524,7 @@ int smack_populate_secattr(struct smack_known *skp) { int slen; - skp->smk_netlabel.attr.secid = skp->smk_secid; + skp->smk_netlabel.attr.lsmblob.secid[smack_lsmid.slot] = skp->smk_secid; skp->smk_netlabel.domain = skp->smk_known; skp->smk_netlabel.cache = netlbl_secattr_cache_alloc(GFP_ATOMIC); if (skp->smk_netlabel.cache != NULL) { diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index 3c1cf65cac87..46d81f638a2b 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -3728,11 +3728,12 @@ static struct smack_known *smack_from_secattr(struct netlbl_lsm_secattr *sap, if ((sap->flags & NETLBL_SECATTR_CACHE) != 0) return (struct smack_known *)sap->cache->data; + /* + * Looks like a fallback, which gives us a secid. + */ if ((sap->flags & NETLBL_SECATTR_SECID) != 0) - /* - * Looks like a fallback, which gives us a secid. - */ - return smack_from_secid(sap->attr.secid); + return smack_from_secid( + sap->attr.lsmblob.secid[smack_lsmid.slot]); if ((sap->flags & NETLBL_SECATTR_MLS_LVL) != 0) { /* @@ -4751,7 +4752,7 @@ struct lsm_blob_sizes smack_blob_sizes __lsm_ro_after_init = { .lbs_superblock = sizeof(struct superblock_smack), }; -static struct lsm_id smack_lsmid __lsm_ro_after_init = { +struct lsm_id smack_lsmid __lsm_ro_after_init = { .lsm = "smack", .slot = LSMBLOB_NEEDED }; diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c index 658eab05599e..13c2fa728054 100644 --- a/security/smack/smackfs.c +++ b/security/smack/smackfs.c @@ -1143,6 +1143,7 @@ static void smk_net4addr_insert(struct smk_net4addr *new) static ssize_t smk_write_net4addr(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { + struct lsmblob lsmblob; struct smk_net4addr *snp; struct sockaddr_in newname; char *smack; @@ -1274,10 +1275,13 @@ static ssize_t smk_write_net4addr(struct file *file, const char __user *buf, * this host so that incoming packets get labeled. * but only if we didn't get the special CIPSO option */ - if (rc == 0 && skp != NULL) + if (rc == 0 && skp != NULL) { + lsmblob_init(&lsmblob, 0); + lsmblob.secid[smack_lsmid.slot] = snp->smk_label->smk_secid; rc = netlbl_cfg_unlbl_static_add(&init_net, NULL, - &snp->smk_host, &snp->smk_mask, PF_INET, - snp->smk_label->smk_secid, &audit_info); + &snp->smk_host, &snp->smk_mask, PF_INET, &lsmblob, + &audit_info); + } if (rc == 0) rc = count;