From patchwork Wed Nov 24 01:43:12 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 12635673 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 CD726C433FE for ; Wed, 24 Nov 2021 01:52:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238275AbhKXBzl (ORCPT ); Tue, 23 Nov 2021 20:55:41 -0500 Received: from sonic308-16.consmr.mail.ne1.yahoo.com ([66.163.187.39]:44322 "EHLO sonic308-16.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238060AbhKXBzj (ORCPT ); Tue, 23 Nov 2021 20:55:39 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1637718746; bh=FKZoy7Ae8g2fJFCJVup+YbOhxC6lR8pSGHi0aTX2obw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject:Reply-To; b=o+0wnoaLLoddnCCOifSoV9Nf7Gl7RVXd1s5Ib6AA9Hjr3X8G6RrSLo7hK+840PO2dep4P36ZmJj/pr42OknpB6ypHPPQ6xuHHiOvEp4beZbhV2vfkWG0E8g6fzlKA0NEpr0ZsQ7H6y6/AHV313Pc+Odw+lSUycljO21oAOm7ZUQePJGVl391MezfgGzSkhu2jHkBGLF1KrCztSeKQYBym+7yKmAuPCfJ4+1aLyz7mkf7bKIqIrSYMW4OEEPkeW50Kcv83zrvoIpheZnBVsMK+Su2q8F2SPNzqbgxIg/b036o0jSWOauQAbAd+O8UskJMZtxAtSUb5TyZZ6MhlHShYg== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1637718746; bh=Fw3f7wMa7P1VShv4P45ZOnt7nbBNdy7u8bLYO3jHjEr=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=GVQTD5L7Hj3lKsbocR6W7X1n1rD23GlTGs18k2GbeB/Y8SQnGMFinqBp37LvAVvirAWfLyiW+XmSaQB59t22sIxmc0cuoXhXMWSKzmxNHQii0MLe+f+5oKkUqNJLIj0WDyHep8mK+b6BTQRL99IcHm4Y6WCJvocQ+TFol8K7ptn3kKkYvyi5/SgOBepusc/IxgW8sK4a+LK2HoKJiYW2O6Cpq9kRlT+J1uaGGgZJTUpvK2fhKveEt+0GpiwQHu+ysmZNOv+UFMXI9cg7bB/Kz3jMxz/MFqcJ8NgG0xctU5kaSN3WM93C0T0HMr2x3d0x07J8lZX/fZp3mGQhgF0fWA== X-YMail-OSG: iV3YhFMVM1lqFYBw.s6ixUNEV_LMBo.FcpmQ5uhOPx7FmkLPMHkV9ewG2VRjP0i fXBpnoOto_ZlFmseGQ3MPVCxE1wWUWiE0EfEXccNni23nej1qaNPyT.z3g2qiO.uJWsZ3avIEMkl Ii_.7nmdlBlCKI1pYkKTfgM0KlW022rKeUl.AWNbdVKRJRNMqBC9bk0Mz8od1yxPv.GuOZls1Yfg HowEhn2wOzaMmBc9q_sYfjx_fHVcOtQSX0qTCWvtbCZpd0UfZ4QyuiEVfmY3sOXfPni2.v3Rib4P ibjeKTzRpFoLGW_J9pbxniw92MrdqUOzG2cWfTGIG_Cp6sFIFMZyN0Y96b7cAf8CllM1Rud_Zmku .XwEgaLKkm5rw7Fbs6WzqiLf8Hcj1U1Urrb6yjX1gffDLhG9Z7kacYxkqLcxSRkqHc4RhbDfSOAB 6tK1FvSXTyd2BBBNheYGIVPoFhF2.571veXF.6groGvnQqMkhPqqIyBby5i6grAsXANL7kjrK5LS 1i3g2yRDjT5wZKI2bdsBYux5Z0mc2XZg.Gj8wgZ_rdWWd_cWEKuH9QziTRGj6UP73bgw7jLTJ.qx PeXz_Hw.4R30e3VwLL3fNWw2Vdy_CdG3aBMfxSJoejVbWoUpD3BSKBJ.GK3x79epIMeQY4iifhdD OGIDCfsoh0.Fc_jtlG9THFe_UPZhOn.vD2jubxf9FMdz1xzRWkh2puYHv8ODimSjeXzl5JGkh1CR XSAXhejTb9uMsX__eF7PBeB_Nn4mPSzZipYxk.MecR1422eY5xUmzODF19jZQDZg6Cky19iMzP.o N2QAAz9QkoBIYtvhjvBlbPpid9_XWljhkIQx41KKaAC4R8S0bm91vklCoaFIxJn9zP.45zpUkEFE gfTrB._ZqnimBhfc7CHNyrEpVFEmRp4P2sn.lm8c7yJVfyEqRa6pVwlWytQZCkK3PTkF.vMtbFTG OQ9O.gbbxS9KJj9aJiitJ07aRxdGTeEECr8pYdqNF2Ji_6wUFiExmc0qktU0jIqEyX7RRgMZkxl5 yMEWZhtmS7ZW9TijFFDcR0.mMJU4gfo6iQpZONMZqZ9WE93UBq5vTt8xFaFObqPGiWKdwTGe541_ M9SX_yECQC9bRm6KYr3zibY0QNhOmwjicYsutFJY.T9rSUmEHR7P9aRtCnsehqHG2a7zXNLlBjA4 P5Ei3CdogSeOIaBOIlcD54t7zV1cuEKbp6tlbgz2MTvYBK7E7a3CCrfYYbtCKllkkX2nJdLQTFCD RvBWSE5eaIPnjg9zXLJvff0JTSU37k3LxBD7ljNMie9D0gSP_cebFuo8RBbS9usVeXobqZubQt2F I_7.prSNDo8Vjn0Bci4MyzSUDY9mriSIw8p0KOYM.63KsSSRMx4pC0N.TKNo9ZMCu.ex6qiBpgaB XmLDzNn28rZQkmJLneIjqpkEkXWjV2ZyZqLPunWmzkjbd3.ZsREvVUCnU7DLoU5oaydcsW82Acdg ByFi28zNTHHfGxj0Zsgo9Z8udo80aaAJ.3WfkCQBEXrBgweTs0FZ2E9D1eF0qja0u.E5QYFN_vJs dRc5NXkSZnqL3woRfavu6pylWFqM8OjUymePviSxqSNNxUeulnJZPkldZCl1qdLr7gvuAABNgI9U uqpAFg2S07KJfoPa.7YV14875IZtFicMqOVpZ5d0h6p0Gnv6N2ixKjSXpelIb0.fpApP498ieGcm Mqfxjn9TTgDoVlXBcJiIvASVaFQrH_9YMKVs7vdr8gyToy_WxuVr1b8KvvZQKuO.SG8DwpXdSmUT BoV._geAmdieKwe5PQKhZUddIQtnfGl97ZvNl2A.BLJzh4I6KljT.chtbZg6HVBdMHRkaePQ2k5s 0zuRN8l0B56eZbx_b7YwlMsEw4WKnmHG_UI9jabrVV._CkWHlecJYaY6dLMuyNGw_zhTd5HDoffq khPctibUOy9Ohh3PugVDh0dhDFozxsW3f6WUdpV5.2KRTXSMA9xKaU0eDP6WqFns_UJZRNqjRyQF OhpzAzHHz4hcuf0KWQm.ZUXWxlxyQF9zqYxANik0fTQbOeSCTjwc.1lwrE4Z770M3TxS7i807ZH6 NNMUAWcJ030V1t2cnY.uRLrQff77XNeg6Ub9abKlWaYVFL_puycDr2JjAbJX0JEp6SrEvgxlE0Ua 6G2nn6W.ZcUkvcrrQ3DvOa6MsV.7_1ArKoUC8BblL46_X6IBAmsdANNDF5FNpRrrnno_283m.vEq 599i8DrukkMrjzb5QD7xo4fjz.MXsrZ9EpOO3ptPpg4hCAxY9YWI8ekAz X-Sonic-MF: Received: from sonic.gate.mail.ne1.yahoo.com by sonic308.consmr.mail.ne1.yahoo.com with HTTP; Wed, 24 Nov 2021 01:52:26 +0000 Received: by kubenode504.mail-prod1.omega.ne1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID f73285a66f3fbf39f2e43e2b2e480b38; Wed, 24 Nov 2021 01:52:28 +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 v30 08/28] LSM: Use lsmblob in security_secctx_to_secid Date: Tue, 23 Nov 2021 17:43:12 -0800 Message-Id: <20211124014332.36128-9-casey@schaufler-ca.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211124014332.36128-1-casey@schaufler-ca.com> References: <20211124014332.36128-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 e6dd3463604e..65dc61067e7c 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); @@ -530,7 +551,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); @@ -1391,7 +1413,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 fe91ff5f8fbe..c171c9aadb01 100644 --- a/net/netfilter/nft_meta.c +++ b/net/netfilter/nft_meta.c @@ -813,21 +813,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 566ba4397ee4..762561318d78 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 f3d30ef512d4..852aaa05edea 100644 --- a/security/security.c +++ b/security/security.c @@ -2195,10 +2195,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); @@ -2349,10 +2361,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 Nov 24 01:43:13 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 12635709 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 B65F7C433EF for ; Wed, 24 Nov 2021 01:53:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238067AbhKXB4t (ORCPT ); Tue, 23 Nov 2021 20:56:49 -0500 Received: from sonic302-26.consmr.mail.ne1.yahoo.com ([66.163.186.152]:35470 "EHLO sonic302-26.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238317AbhKXB4r (ORCPT ); Tue, 23 Nov 2021 20:56:47 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1637718818; bh=I376tfCBPkXxTvDHbGlI/BnOlmvs91pFbxvhLdOiGlQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject:Reply-To; b=AjXOCBWkXw6CUjCUTURYdVAil7RKM38bVxeitLnE9qmmtmOCZudjw0Wf10wPqFDVQJH/aA79hpGG5qUGaJlmTNhfNj2mu6zBgSkFZw+L9d2MDR7d8Jcy2/an0si4vdv5/LLtahYOWJpMRe7DRUMTRGMzQatlVMlN0ePkCrKwUBcnIV7Nzv5Cz0B3HKX3VcXY54N3Q/1TxlEQrZkyEFwj2H5gCSwtR5PnZBj66IkvXIU9JB6/qEK2UhSmoM1UZFtIPfMmJeKGqxxOa9pZvuxaT3AvP2AMOUJRvtMgH6xfVR+M/TjwOXPLdDK/W1YoQ6CYUakCnfP66l3+9X1cN3JjFA== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1637718818; bh=8CAvlH9pIrN6tqkD9y7eT9tFVoz9BLn1XbiHj8eX2H3=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=mUrGlhEsDopGb+P4lqS65/Nz1GHd6DLBv4ta7WtVxtsO2cOAKUWV8Y5fgurk9aJujkU1WlQ+GsVzESMH+QJsCbVgfn/aTVy/sRfex2drrlcxQfNzw8xW+KbvoSAwJPhu2A+SzeEEiDgoheCRMmuCeMuGJqvmGEuvubRjLwq5C5CNC3rHyaONOWc8XldvcIgv6/48rp1bnzPN16Ios0mrKIl2wFxJsAz2wOiONHIfsnqahOirJdWJZ5zUcyfHZ5PhszmJ+QBdw2vJFZ1eINWj8UHgru8G9HlgK/a5VuLR6pAS16WsYPvLMUJ4hltn/9d4OuZxcSywA4cCvkz79txTmw== X-YMail-OSG: NYPF2AkVM1k1W5ux.zWrfTFzj3P0lJanIwrEITwdBb4n0.pjk629gYDTGwNlLns xMs6rIqCcYIioN4le0pdacI.kqcd6dV2OXEeYsALhscubLp3X5dRVkZEnnaHtCSd_JMMgbCbP9S5 CQEggojcVlmY37C50W87NDeK9vk9qEV5LZ_HgK5Da2rNCXDekG3cqJlWXxCnOGfr1AvLAta.O6At wvRaiN2edYmo3FMcG6d2tNKkkm6ZExQRY6ONL2yMjSXwLZHzog66tE9m2sL3boDgsk1sbxZ69.Pb _726wj8nEvh6Mq_1Qt.ZF3DjhTpDTylh6Hz6N.xWiwYMwpdDx6ljokhQybkknoDZ5T9MmXvqZx1M 83WEYrvKzU.EXJzT15QGwCe1O3.1huK.CeW4Q6fNGid92iCRUZu.K403n24UWvRcxxEIup.vUWbS CxhdUGZ1uUCbQNQ2Bj8v2uTPYIcH69_VmYGvoLaa1PSe8mfUCn_ZWICn.NapkgZMXbjWKWoxMoCO zw_QI_1P81wQg0tBsZzr1TBu2Hdiz5cv1qwFGH5mhxkzcnUtp3ZUuQ8YhVG5ZhG7SbyNxRmgZbHh XVVEWTIRcCy9bgA_LUDDb9I0BVuoqOnF8FFxdbh2qx5NBmYmb9KhhzFjBWnOUYe5yAYrDoTjbUkl mOWJ0rqNheCQgE7MoYQFIbnt9Mo7_mPJue5p.8wCvjpT71bs3dWaATw1w944aNd5gOg60LeM7sFT JfWc9EzEzF9p1xuIdkRRD.WozkNQlUCuDKOowE5joKV8cmqi573yl7TpXY0Ij2blspGT7LexdfBe AcoHVxAhmiPZHZiMjhO0McuZ2pXk_UXyIUUXd0pFHmK6PzmqBu_jlz9C19U6MCH3tOtKU6YPR.vK 8QsxOxL4V9Z5UnhpJLrJE7XBw3BxxcaQgWItSl99m3QsHZuhRGW55ggNAUt2FRdH1JeY2YYImLYq LW7TYksCVwiUzSeLPQKYxOwJHQ8lP7utpGukiQFzJN9GLCH7BRKYEi_5.pYB_XQdGEzCW8cFX4_v ._aJ.0Cvjzi_LlvwxVCOuxd65cxpplg.y9AYj_cWcBJU9naF_5craWZGBhBP_5OwX5jKlWgk7vR4 S.Xfaa95N2RwLD62kE5cz5IMLP5mEMKM6srRw34qPPUWrKQo3c9dEW1w7wPcafrB0o9IEM0X2rhm .xxUslRRwGaA.pTNhD9vQw9teuXS3ihEyr34yYkxRZf5BCvFDZN.Hy_lZX5jHKq4nVAihGNxbjwl RkJ5Y4zoRVCI_0Z5OcStyPh02GYVF7LPUu4hyHqJmyqGrN08VTdZ78kpWgMV3oZSKo2BGO8XQIUl qApWSaErUW9DsRFrmlWKSH5WtGvuNxpoXYsljZSsQwADiitrKLaNRodqQ_EljX2M.Kw5QWhTC81l y9HCOcmvBENe4HD8XHvXz29DO_LnMyDKKhG.ibWDxbOj_cs8K4RTMIEi_GxOwxt___jdprImgqVO 1sURB25rqiVv0Ae_agCFDU6iZScqQUY2fEdwvkQU5Uu3GltQQrS1yPIV2xj8ZntdUOaW6GTUDIAe i36ClUewa8MKs02CK_Af0bwHWjyvlTS7_DYsgho55IPpJ2qjZ6V.r2D98aIBlw8V0Kq0UM3PaG_B sFD0hVI5_n6LVcxq0lvmkFAUYTaZ5n75isxAjJd03874.n_I_rAHuA4arQMtHsxtbXhCEOR51XuU F6b.HH9AM_qUGmQNwjmA26XwbwTX4sacKxSKETY7_NTVKiNQ064hR284XD2np.b1cBIz5QJ5nokl CqkzYreupn3R8kNuPOyjREf9z2S5sUTj6BRuFzh7lwRMFJLNK.oTyv5nx3iZ8urcaQXaAZkz9Xxo lnbNWIE3tpIeza_e_P6gOKll1ExxKmdJAS1JPla98Nxe_0hPBKHhRsUJKCjiGWNcX3ljEHaDPCWw O256zp_Q2s2fMkC5meiQOJFOEKs.euFe5iPr75t2HYKm5BUxhyRNu2SIVrtkdH.JJU9DZ0q.6qeF S0UXOKm1k5ANE8MUfiA1NZhV2fDGt3garEpy4VJaye3.0Cjgo5EN.rfSGyPBHDzTaGl.5.ZiCmHR By.GKrIpIdzspYERXgL0jKOi_XoNnTf.HFzHpk2pUjDhzcN49O479U7RzALP1CboMoPA3k6mYmXa NuuXnHemphCTnhZfYvHS9qOFCwLOdjKiVjyKIb3AMBVpNdt4mi_JhrH76yS4CVvSc90jiWpWrkf9 EtG3wMqOyHRtUcAzlgICD637MR_A4b9hTsNL0Q1OR_ohfuJg5XDf5fJJfLsVo4w-- X-Sonic-MF: Received: from sonic.gate.mail.ne1.yahoo.com by sonic302.consmr.mail.ne1.yahoo.com with HTTP; Wed, 24 Nov 2021 01:53:38 +0000 Received: by kubenode511.mail-prod1.omega.ne1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID 2f39561b52daa71f71500fd09f46c636; Wed, 24 Nov 2021 01:53:33 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, jmorris@namei.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org Cc: casey@schaufler-ca.com, linux-audit@redhat.com, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, paul@paul-moore.com, sds@tycho.nsa.gov, linux-kernel@vger.kernel.org, netdev@vger.kernel.org, netfilter-devel@vger.kernel.org Subject: [PATCH v30 09/28] LSM: Use lsmblob in security_secid_to_secctx Date: Tue, 23 Nov 2021 17:43:13 -0800 Message-Id: <20211124014332.36128-10-casey@schaufler-ca.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211124014332.36128-1-casey@schaufler-ca.com> References: <20211124014332.36128-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 | 20 +++++++++++++++-- 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, 122 insertions(+), 29 deletions(-) diff --git a/drivers/android/binder.c b/drivers/android/binder.c index 49fb74196d02..01cef18f942f 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -2719,10 +2719,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 65dc61067e7c..af712b61c949 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -550,7 +550,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); @@ -1406,7 +1406,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 121d37e700a6..22286163e93e 100644 --- a/kernel/audit.c +++ b/kernel/audit.c @@ -1442,7 +1442,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; } @@ -2131,12 +2140,19 @@ int audit_log_task_context(struct audit_buffer *ab) unsigned len; int error; u32 sid; + struct lsmblob blob; security_task_getsecid_subj(current, &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 de22e852373a..fccd4571db5a 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -670,6 +670,13 @@ static int audit_filter_rules(struct task_struct *tsk, security_task_getsecid_subj(tsk, &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, @@ -686,6 +693,13 @@ static int audit_filter_rules(struct task_struct *tsk, if (f->lsm_isset) { /* 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, @@ -1109,6 +1123,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) @@ -1118,7 +1133,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 { @@ -1362,8 +1378,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 { @@ -1524,9 +1542,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 38d29b175ca6..be7073df19a5 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 f1e5443fe7c7..daf554915e07 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 80f675d884b2..79c280d1efce 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 4acc4b8e9fe5..62c0c5b847c6 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 762561318d78..51cb4fce5edf 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 852aaa05edea..cd3ac0a5673e 100644 --- a/security/security.c +++ b/security/security.c @@ -2176,17 +2176,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 Nov 24 01:43:15 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 12635711 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 D9A6CC4332F for ; Wed, 24 Nov 2021 01:55:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238713AbhKXB7C (ORCPT ); Tue, 23 Nov 2021 20:59:02 -0500 Received: from sonic306-28.consmr.mail.ne1.yahoo.com ([66.163.189.90]:35158 "EHLO sonic306-28.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238955AbhKXB67 (ORCPT ); Tue, 23 Nov 2021 20:58:59 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1637718950; bh=7MiUFyCmfkC//4vnaYq/YKc6j4ocqCWB/2RMJPU3nwo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject:Reply-To; b=hsq3iHIWoxu3jFteNF1W4lpWvr9tmc1iU2bntRgRLcJSJaDWA8+fLt0tHUzvht37ZlPjHBlJUCo6nHjiPHl1gxpRLmK3ANasBQ0tBUM7xBakuZytoDNlmrvzY76Cr/S+EKvkGRyAvegC+E+MIec1YUFk/soYaP9TDmmVSppCy7vThBjiduZMfwrcqVfzp8jXiybHyr9ruGEuDMxfX+kGfBCHkHMtOgxPhasy4bc+TddvDPfoNb4c+4kMAD8T1axBo/kYqCTwu3JJ+ZoyPvlCrTHcgCYcYmpoMwf2M0Dj/yE1d4IUAyxkYu9COZTNtTnWUJi+PZhJyA82SsWwNHkPuA== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1637718950; bh=xbeUysdvsbQ7KdjsehGv4BIwjhXQtvkgXbFDYAs9GnJ=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=S/gDAKqftZ+iR+HnqFPnYSj2E7lOruCEMKInEGGxIexX2zHaRNJ7ddIwbJGH9ZvoaBwhJoZlPR/+cYx31QVBj6RbzFaEOAhqzP010cSAnakRCEk6MF7F0g2zy3wwGYJFqBCl7QkfNSjFnNTVYeGfAKKt2jAZqdjqn4vAhs4gifes86DPXZUkw5uRG/QkSgcJEPNqTowVI+eUsl4Z9U4jM8AZJDG5oIaCxirYX8oumnH97N22ZtL+zrA69/x8pRqSG8fyrgKOVSlse+oz1sMLF7SZgOfex7GhsVvRyY0w6sgOz00Q5HfDiwf21q3zoZ3nYH60Ybgbe6cOYnbC5iRDKw== X-YMail-OSG: .NGEq8kVM1m5ea_5_RdkZfniA4gsr5x8kx74xZIAgxiCDKsjrfkfMErTj4fjY9F kE99kkOe1los1G1bHmubDnVXdBVolkcHmXmc3SYTtO1W11ZPSIEbE8uUBAOilmRGvh10DEYEk4Zr 62OHDb6wbze3ouU5cBQ6dwxeEcNSsh.Cv.CsZ_PFxvykto0L3tUO9MILZQRN_wJurEoRfeqm7Xr0 7M3ilEeUt1dzNGmJv7qsTaK.fbsR7q58QK5xLBLuTmcfTnr6ahiWauUK0h7vJJFPjVVOiQLiANA1 Ge..WshoaKw5Q3u1ucjJZ_xkWoEdQcbZBRZkj5_xN38GIM70iuQYgEHVyNBhLIqoI.cihQF8n7Px RTq.lWDGg5MP7MTTQqieDlkrvh7MOI6U14rOzC9L3.HJgLCRNgK8velXPwlxV8ZPMB7pKnXFeI6D l5tcXC7_IYGlQg_zhuhRuYDD3bdJYTJ.M77UXPx2bIIRxYnieallVmlybuEuEklxiR8kev92K8EP WggSuSyKYQyUD9sAcfWx4vvATaHOV6.zb4.yZHeT6OcWY55F55G_4EfBB0S_QgzduRuem6GPR9KE tkFF_NIX1FrazIG0YJPNec2J1UoAdn_49N5WyhPKAkuFxBkHbN.SYeJf7DXCxyowPcId7ZJFmpX3 wa0DMxmr8AbY0VlJIYtR3J7mRqt.QUgwAIxM_TkhWub42ulruJl55u838Rng6_trNvvByFKdu.0r XotuFQVeHQus.N_z26Epz8jEzXbshrfduXQd__.ysr_CjuX.m0HLskdt_2uzxB6PrYNA2PnZMOAT 4GN9oDqLtr42d20Wk_eBwhDLcXI03BEWHajw.M4.8i70bUeYPRVyl.h3iiSgzlqRKNIjUPSuuEHZ 8V.aEGl5YvPVVGATaLNpIFXNbOEWfOrskt.isbm0mFdS2y5Hn5BA2ys6ekF.xQ0O0Hju_Q5v8jkU xyhtvoN_XvUxnEH5AvByRq0eb2IcEhfVaV__elDKY4Okl41eFBRbHcPsoQuUyFK6YLIbPq_HJaZU T9Qk9Acrj_vpKNOVAo9XcDKaTUcszVFHs9vsGH77vXy32ebzduPsxn4Ltv2FN7qgXOT4fRW9DVsm 6IAkIA0XD.saWSddrql59gPGnADHdjNsCW7DHf4z.izhM_ZTbkN0V_tobgZmJRnstHs0XGggKNro ciakCKS0GXcJ27drxX3lA99aAED_vARVJbVY_mvqhoI2Az5stgtJoM4.1dTqikAZWXrYF3E6ta7. C8C4f6l5KRoseT8cUT.aaU3ZzSVkHim3lMmdWv3udzaOKeyccsT2MXg4WOk7HBuTn9Qt_PMnKqA2 UzvHSqZ.h7oQnQli0yhhpZ2ob0sdkZPnKzRMdL8_7bAv5GRhIH0m59b6wm5JC89Oict0nhYhosXM OHmJwngQ3JWM2pQPELZ.LQwM5.5IS82m9oO1AmNfvaFs.i6qozFnGpTDKGUAFgmKBjss3GfwmChx ACDx5NTjA2IsrqAYZbH1CohCTeig05oFuz4T65ee1hvw0nnVJUDqGYfPE1WyX_.QDcAh1byYLw.7 QkxKY94HsO4F2.skmVarntSfZcaL5h6GCPOFEnS_FV.ygqDWLPWa4TSnOb3SRjdrQCjj2pB95X0D oSXdBWcFhXgFBoyj.WjaXGKhGBAuYwiACgx2pEl_XZnI_Li_WlX02zm2sxDdggkusXssaoOtOP_a Y8DdqyFBYVDKSnqnheojHWVkCww4C3fSXL3RKEUJ2Kg5bob3EH9wu21PYpOB0Y5SjuHkFDtv.EpK P6WWrSVxcAdT0DVFuv96cIvxudRrWnxDcA7pWUHWpaFGElDgdpwzilKloWGx09wIkapkCUFDa.Mk 25moOhK1.Jp4TsRUEU.cu8KnE9sQOeMmGa4mWlOMV3fDf2kbjmXqOQnkAw6klF3S9ZNr87aG7ypv vXDebwH5kvl94vuMz_eNZXl5U5KUKkT4.D3158E.zm9GRx_CVG91xnep0Ymxe8pR163njWjr_igE ie.xYTOyq4yHAbSYETDumuUybuV_nqnx3ZD8s78Wc43EB4TfZ63SbNTw.6rb9puWp5EjPUhFTkeO _040hgJRzYsswmtt_C75kZN00JFvriCLAA8Xwrm25CUnJU0G8YKYgebA.piVjA0vnTRJTxsGurwv UY5HWkk_uQANd380sRMBoDqad71Q6QSnrZ2q.5_H37.FEmU2_hrMNLz1g4ew26Q4YMyVMcyV_AT. 94JpEcBDB48bNSOvhlr7OkW4HzaJrTj6eigiBLAxhhq31Q5bCbdA_Z1LFficGBXmrhstjmhrt2zu NQtGDXZedzds4156_lDVVYMba868quF8hREw0k3_ams5j X-Sonic-MF: Received: from sonic.gate.mail.ne1.yahoo.com by sonic306.consmr.mail.ne1.yahoo.com with HTTP; Wed, 24 Nov 2021 01:55:50 +0000 Received: by kubenode511.mail-prod1.omega.ne1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID 642dde53d69d58293143a094a618e31b; Wed, 24 Nov 2021 01:55:45 +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 v30 11/28] LSM: Use lsmblob in security_task_getsecid Date: Tue, 23 Nov 2021 17:43:15 -0800 Message-Id: <20211124014332.36128-12-casey@schaufler-ca.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211124014332.36128-1-casey@schaufler-ca.com> References: <20211124014332.36128-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_task_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 | 14 ++++--- 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, 96 insertions(+), 72 deletions(-) diff --git a/drivers/android/binder.c b/drivers/android/binder.c index 01cef18f942f..780c7e265f3a 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -2718,16 +2718,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 42c99237786b..efd6e88d57b1 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -503,8 +503,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_task_getsecid_subj(struct task_struct *p, u32 *secid); -void security_task_getsecid_obj(struct task_struct *p, u32 *secid); +void security_task_getsecid_subj(struct task_struct *p, 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); @@ -1206,14 +1206,16 @@ static inline int security_task_getsid(struct task_struct *p) return 0; } -static inline void security_task_getsecid_subj(struct task_struct *p, u32 *secid) +static inline void security_task_getsecid_subj(struct task_struct *p, + 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 22286163e93e..d92c7b894183 100644 --- a/kernel/audit.c +++ b/kernel/audit.c @@ -2139,19 +2139,12 @@ int audit_log_task_context(struct audit_buffer *ab) char *ctx = NULL; unsigned len; int error; - u32 sid; struct lsmblob blob; - security_task_getsecid_subj(current, &sid); - if (!sid) + security_task_getsecid_subj(current, &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) { if (error != -EINVAL) @@ -2359,6 +2352,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 || @@ -2369,7 +2363,9 @@ int audit_signal_info(int sig, struct task_struct *t) audit_sig_uid = auid; else audit_sig_uid = uid; - security_task_getsecid_subj(current, &audit_sig_sid); + security_task_getsecid_subj(current, &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 ffbd8396bdc9..de165c2cd55f 100644 --- a/kernel/auditfilter.c +++ b/kernel/auditfilter.c @@ -1340,7 +1340,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: @@ -1371,8 +1370,7 @@ int audit_filter(int msgtype, unsigned int listtype) case AUDIT_SUBJ_CLR: if (f->lsm_isset) { security_task_getsecid_subj(current, - &sid); - lsmblob_init(&blob, sid); + &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 bba31349ae3e..7cd70a43408f 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; @@ -667,17 +666,9 @@ static int audit_filter_rules(struct task_struct *tsk, logged upon error */ if (f->lsm_isset) { if (need_sid) { - security_task_getsecid_subj(tsk, &sid); + security_task_getsecid_subj(tsk, &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); @@ -2703,12 +2694,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); } @@ -2724,6 +2718,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; @@ -2735,7 +2730,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; } @@ -2756,7 +2753,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 51cb4fce5edf..15b53fc4e83f 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_task_getsecid_subj(current, &audit_info.secid); + security_task_getsecid_subj(current, &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 6190cbf94bf0..aa31f7bf79ee 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_task_getsecid_subj(current, &audit_info->secid); + struct lsmblob blob; + + security_task_getsecid_subj(current, &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 dbba51583e7c..2fedda131a39 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_task_getsecid_subj(current, &secid); - return ima_match_policy(mnt_userns, inode, current_cred(), secid, - func, mask, IMA_APPRAISE | IMA_HASH, NULL, - NULL, NULL, NULL); + security_task_getsecid_subj(current, &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 465865412100..c327f93d3962 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_task_getsecid_subj(current, &secid); - return process_measurement(file, current_cred(), secid, NULL, - 0, MAY_EXEC, MMAP_CHECK); + security_task_getsecid_subj(current, &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_task_getsecid_subj(current, &secid); + security_task_getsecid_subj(current, &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_task_getsecid_subj(current, &secid); - ret = process_measurement(bprm->file, current_cred(), secid, NULL, 0, - MAY_EXEC, BPRM_CHECK); + security_task_getsecid_subj(current, &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_task_getsecid_subj(current, &secid); - return process_measurement(file, current_cred(), secid, NULL, 0, + security_task_getsecid_subj(current, &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_task_getsecid_subj(current, &secid); - return process_measurement(file, current_cred(), secid, NULL, + security_task_getsecid_subj(current, &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_task_getsecid_subj(current, &secid); - return process_measurement(file, current_cred(), secid, buf, size, - MAY_READ, func); + security_task_getsecid_subj(current, &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_task_getsecid_subj(current, &secid); + security_task_getsecid_subj(current, &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 2e74e5e88d64..1b9f33097216 100644 --- a/security/security.c +++ b/security/security.c @@ -1906,17 +1906,30 @@ int security_task_getsid(struct task_struct *p) return call_int_hook(task_getsid, 0, p); } -void security_task_getsecid_subj(struct task_struct *p, u32 *secid) +void security_task_getsecid_subj(struct task_struct *p, struct lsmblob *blob) { - *secid = 0; - call_void_hook(task_getsecid_subj, p, secid); + struct security_hook_list *hp; + + lsmblob_init(blob, 0); + hlist_for_each_entry(hp, &security_hook_heads.task_getsecid_subj, + list) { + if (WARN_ON(hp->lsmid->slot < 0 || hp->lsmid->slot >= lsm_slot)) + continue; + hp->hook.task_getsecid_subj(p, &blob->secid[hp->lsmid->slot]); + } } EXPORT_SYMBOL(security_task_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 Nov 24 01:43:19 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 12635751 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 02E88C433F5 for ; Wed, 24 Nov 2021 02:00:14 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239830AbhKXCDV (ORCPT ); Tue, 23 Nov 2021 21:03:21 -0500 Received: from sonic302-26.consmr.mail.ne1.yahoo.com ([66.163.186.152]:35295 "EHLO sonic302-26.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239742AbhKXCDU (ORCPT ); Tue, 23 Nov 2021 21:03:20 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1637719211; bh=LIR7IJw8T+x6DrfrqDIrkMhlikVn9ymWzPpYTj2lKKo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject:Reply-To; b=aJWKq8VebWEYg/PkaK5WlyaGiDVAQ7NYD7eoGAocsdoyz4Hzr2dhyjOyp7OdO1dX62ePmsDcLmMZ5x1/rEoRp2PndA9ZHs2PjH4FRX4AcdDeiqVDpTsIZsfHMHugOQS3wI4WLpxxOvUbvFhxf3Zv+xhIzZW+675RgPNjpH760736AlLDBkYk3R7e2MKJ22TnsS7cBDW7CVjLVqFSs/KA62CkUEYpgUyQSTsvdueUTZ1D6dHwgqdGazGhMhFiQs6EeobGM4gzXsPGxgwGqzdgbPbmKEbXBPk8mHEZ8i/Mrz8H9IcuOfTWLXP+ewSsSHgADpwybpY645/rjQY19nV1iA== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1637719211; bh=34Msmpgwye2XlUVHBKdPvOxepkEtgZbJlkYOHboI9pZ=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=r6CcbetnsMJ/WAyaQgzH4eNxvpMgLCno5BQSnAHNOejSOylOiNfvef9ZQoAx/y/e3Dlqbqtp6lkUs8tfEJCt8AkT5eAMpDLOOjXX2ZSTbPaMpXeomPDoXit9pf/Xhp9b3S0zdlUCVNSMxIcqg61HcwqdBAFhschj0XCLsH7n+Dp8N3X0fE5N182KSYbNOST7cdchS/9exm7a8Lmp2nsYRPRyyTqLqlxlT+bmPXyKv03mwQCazkornfA/6A4b9htICJq7OBSR1+z8MGtNS3Z29oGc3QRld+8gNUqrfAAUwj40ihjX6ogD0Dc9hAbIYMVIUPn7Kz21zrSXgIX1jH98Og== X-YMail-OSG: bH3grpYVM1lwnuS2O_8A1C6_Vhp5jVacAcKYtMrw56uCDzhDYTSIOQFIhcaaMM7 BSimMPY_rhL9DQq8_oPBs0HQL_njN9hP.oRRS6i7EynqUwSqSs33.uQZp1DZBJwvRC4G3buCV31q F6c0wK8ksKG1PZV8O.a2F.ZEoFxaVSsRrfujYSqhcJsTrYtmZjhB4jNf9Pmr7WRYpNa9LWqjyWLG 5fTjQKENmPfPAchFNhVe19oHGQoFvVXeQLrN8rGgCyupEvMQUjV1Jbv.yfu7gL_CZ6nJXiDUP_JX 8Ys.vAYTy1X4p7FLCUR6HFvZpnI7C5Z8xMc_ZjHgs7RmxrEar5LJ6e5gALoLi0w1xQx1d1shG0rB Rf6Q_ZrgdFu5N6RHQW3vruhl3ENCLe_ZxMud8XO35A_TqGinJtDa43O.OUaM2zEaj0Q2nk30Pzhu TzoqoWSM.Bmq6JT2oJxkbNNxOETK0ycSwcDIXj9Z5Mak5OFFuCP2O4j74wE3hpBlkYpboj7W8G1. 1kX1HNjBIbDCa_2KDoTHxga8bfQKExz3LojS5Ohbx2EqmMWHvYNVP6zbpdBh4TJAqnnYnKWWH5sT g2a17AxC9KjfquTjuHzRJAW_dvodRyzb.oew1HKrc4CALuNOubXJk3dgy_9bHmoqYHqqFtM9cGFG Cz4HLBuWw2Rwf4HFCcKhsoO63m0zszsFy.7tpSZzo1_DuU4G_._.rAhm0Ub4j7v3MnOpTPpgGRkw ZRZpxN3TSWmfljPIM3GVeRYfUxzfC8K3fHmiED7K1kElN8uyfkjCwc6EhRiUoECDZqHBljB0jHoc fpnl4ZkEQmSD4.j5lPVRezjtQVRY99u_F2sZYHhoNFviRnx0DRGvN74HRbslGa.tL1ZES438lC36 xkXnkO6BCBiUb2KVDSDHSOt3hC3v77_jFbzWVCB_Mo27hqZTbvmt5bacxW_4HXL.7v.P4HulTMet 6w6DdqgOE.RS.3aFjbyqgu7.Fu72WQZxuNNfeU.NGnLmU0e3psMw3NfgpIOsCmZupHcoWE74f.EY fAupJrptNnpNr9.8SjHB8nmxdNZ80KlTGIR0NV1ULJjeN5cUOK_co43ozo7FvgTTynjnBMBOCAsM 0XPZLUlx8niCKk7ZeO10lfkIwNykBzxTCVa717OYi72VG4HTYEtnDtwNAh85vF.rQWHFeK8xmwkx OXqDaiClPM2vba5jCvOps_b6M_Al9kd_fonzvGUiS19mezkSQfOmIskj6AtO1m2jBlaeefLa5nuY Qp13W6snhtuLqXCM1MvKO49RLlQrH42W73JIjmqXyyjgsAcZFhzzBJG8Ki1MthFbUr5Xg75EbrL2 TE0OXW0.gOUdojZwtposZj2DXH0aVhngN2riICZBa7UiI5yQSQUQ3y.ydgNCW6r4i69TPBH.ufR7 _TJ6D2iUOXL5to3wCBKl5aLDkOq1hMduQ9Mb8wlZYTdqI7AppM424couMIMuJ1Qqbwmd.Ve34UUy vT9Dxrjw7lPH6obO3OgQQ9VV5oWGz1i1I4jiOC5f6mbxCODPLO6WGYYNc.eeGUUL._vwMjRa4tyq UbNGXvar92kIa1oOxW6XQxuAnPR1noofW_Q_yMioRnw0qT1ycI_LpuGYplflYWlXpgoNxRfbgIOH hwBDiZgKIVQowA4WnRmy58V1uv.NtlAZ1ryPnzHfw1HfpmSlQs8PyysDyRx0ymhHVSrVwYAB8Xcd KLqrvi4xnpVPk2DHpKMA7K5u7pbG1GBTe_NL._L9GQuVGem7WcJJoNEjoy5c1nzZHiLVeWqMZal2 Rl4LrSRfLsZn5hKLhXWarxu6X3CmEHUtzgk_ys2oEIg5.iD6t6KSFPvVbS5ooyyI1FNZBRV24g3r neO.XcrHv9pORakVznumv_d7uZ7EGOxrthY4.C9gKcaIdmO3LYJVcMwjrTFEkp4JTGMPH.RSM2QC Jh56GWo6sCJ6VKZjMO418zfXt3IatTadw14G6OUt2kiK.QVBhfqsNaDufJy6SllLEW_4Ru8G3KKQ o8TJzdZpXyh5R0CMng0VwbN0TBc1EjcqNsSZNWHIPMqg8laBKyBZwAy547T59oKOEmVnQGODyqlN LmGcHVpVpu3aGVyNWtYXH6eQLO4wevPDaH2GWM5PxKzOTjXoV8MzA8Q_4jvlnLwFsrm35oB.tF7n _aZ8fQmYWjY6hGpadG5TTtqWFHL8Dowi1y0fJ5ubxgqqI.m0sPeX6Wn90q8vf8SHkb2CZFBQ5I0E KomiVh3lkdPuMHqqgglAVnEhJ2A2HYZJkE3ROJ37lwSoyv4myvGPDdFtXXNuT._SMnb9h1gplpRc ksHmO_XbADIIbtulHovbz5X.xCkA4w2JXhF_7.QT7sByAew-- X-Sonic-MF: Received: from sonic.gate.mail.ne1.yahoo.com by sonic302.consmr.mail.ne1.yahoo.com with HTTP; Wed, 24 Nov 2021 02:00:11 +0000 Received: by kubenode542.mail-prod1.omega.gq1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID 71de488fbfe39b53bec47b0dde9f2e8e; Wed, 24 Nov 2021 02:00:07 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, jmorris@namei.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org Cc: casey@schaufler-ca.com, linux-audit@redhat.com, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, paul@paul-moore.com, 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 v30 15/28] LSM: Ensure the correct LSM context releaser Date: Tue, 23 Nov 2021 17:43:19 -0800 Message-Id: <20211124014332.36128-16-casey@schaufler-ca.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211124014332.36128-1-casey@schaufler-ca.com> References: <20211124014332.36128-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 2be77ae9ca52..de8f0661e8ec 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -2469,6 +2469,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 */ e = binder_transaction_log_add(&binder_transaction_log); e->debug_id = t_debug_id; @@ -2771,7 +2772,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; @@ -3112,8 +3114,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 ee3bc79f6ca3..194bb09663e0 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -137,8 +137,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 b2a1d969a172..89d50a7785d8 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -2844,6 +2844,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 @@ -3345,8 +3346,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 1b82590a6a59..0760cf52dbfd 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 * @@ -570,7 +601,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); @@ -1440,7 +1471,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 8ec64e6e8bc0..c17ec23158c4 100644 --- a/kernel/audit.c +++ b/kernel/audit.c @@ -1192,6 +1192,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) @@ -1449,15 +1450,18 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) } sig_data = kmalloc(sizeof(*sig_data) + 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, sizeof(*sig_data) + len); @@ -2132,6 +2136,7 @@ int audit_log_task_context(struct audit_buffer *ab) unsigned len; int error; struct lsmblob blob; + struct lsmcontext scaff; /* scaffolding */ security_task_getsecid_subj(current, &blob); if (!lsmblob_is_set(&blob)) @@ -2145,7 +2150,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 7d256fb2ec03..efd1a2a4216e 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -1112,6 +1112,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; @@ -1129,7 +1130,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="); @@ -1342,6 +1344,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; @@ -1376,7 +1379,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) { @@ -1533,6 +1537,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)) { @@ -1541,7 +1546,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 be7073df19a5..dbba700fb151 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 daf554915e07..de223234963d 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 79c280d1efce..3fcf44342b14 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 62c0c5b847c6..5961a9b17f66 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; struct nfnl_ct_hook *nfnl_ct; bool csum_verify; + struct lsmcontext scaff; /* scaffolding */ char *secdata = NULL; u32 seclen = 0; @@ -626,8 +627,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: @@ -635,8 +638,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 15b53fc4e83f..7cb6f27c8cb2 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 cfd75659e7e6..5e6d088d94fb 100644 --- a/security/security.c +++ b/security/security.c @@ -2363,16 +2363,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 Nov 24 01:43:20 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 12635753 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 DF4DCC4332F for ; Wed, 24 Nov 2021 02:01:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234203AbhKXCE0 (ORCPT ); Tue, 23 Nov 2021 21:04:26 -0500 Received: from sonic306-28.consmr.mail.ne1.yahoo.com ([66.163.189.90]:33012 "EHLO sonic306-28.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237091AbhKXCEZ (ORCPT ); Tue, 23 Nov 2021 21:04:25 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1637719276; bh=FOpEW3CNmazvtueemopZkXizWcFpSROpROYQ8oXZjDo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject:Reply-To; b=WE4tZ0pdgh+Vth11BQRrTT9Qc3H0tHzcQg1H9l3+ynz3zPQTIMDGfCnc1xuGw1fBMRdMBnpZZHpfRUfjPWtFzzp0ZDPSxzS/6wOAUxdeR7BT1zk30ANhoDwYACR3vfSq+yD534ynn3SB5B2yI8adZ203o78cs/Arij6olu2/0ez2t0ti2YpiVOc5zmppBbDIU/PRa7BYeed7l9K/nUx7qiARC9WneLyqqUGu8zMscvpUjnzbGRdhQNa7AVWF1wrMZ/4bleKIrxuhCrDC95Zf4UQwhL+aFY6wDabF760lwXH5uqulIBItoFEnhkb9KYABghPAcn2aNKWIN8unFScMxw== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1637719276; bh=NS41o0yHTgCqYO6lZHa1NY3GgliMezAgBT9vPBjGB15=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=YrCV6Wa88toPnU+WdsPH88UeUthbJRA3/YgRx2W5RChyDkqXMsqqT27u2tHiQ5oM0dhUMle7fhR9bu8UL0sTIePmxJZkv46YFdneo7Cp3FKDsa9UdMWnCQeWVq374YmZ2RKDCyrMFJD4xGJI1nCZTHFWguK8nICZ7Q/x2OP5As4R+fP4CxdbPjvXrudwYvsffWbxVSW7NgfYe7E9rHZ/Ac6P9HninJevt/ZsYyDJAn3g2qJfTTsQYc8Helg2JEdB2DMJKYOG1L5lDyBXBFET6JKwQE/RiH+i6xfV/zJlwDZfRpuudNr61CetOMgL7TIdwzh9Y9MyWPEgL70St+ScMw== X-YMail-OSG: RFIjt8MVM1lR4WNSyteV5GpDndIDAhSV2kcC3kDLcoe85lRW5J0k0ydaWU_NUCd iLhlkyE7sRNS2oELJ1rT1O.YyGZYSLLYPMOONQ1lX7o3DqMucZonmg2ZDe_xnJrVopObbz7cZN4x s9RULl5cYpCfCxTsxosOonhWCWv8T5yWQkcPQ3wfD85TM32q7V7gvm348dWK8WHZWq2qLpu6Wvaq wMi.EB4DZFTrL8sDzF8ztpSJq07IoQLfluks_un2XyGby_hzbuVn3_M0zhG1FbVEt6DIatAMO0L1 If67I0J6fRBhg9zFD9shEC18gR8KQnP.Kfx7d3_uwWOiYxS96hXis9lnyKfiWLn7fFU2q6tBvmff HY4KvJf41ZluWqjJ81ZOyIqJrJMG48nRa363Vfhr1vv4ziKtCxYJh93FqyCq5HSX2.TxtEPVUTyl nlw76O.86q0WVvkChZZPZbC9c0Tg6m_4e6mhB0ysDNTHsS9lrdPLGfVFo8dAhriDB0I4KaKmX2xm 9M0ZGDCq4Elf0.Q2gZmFmkc8PJeIxBZrVfKwMC60TjMr6KTVMyAQ.B.u5PkNd.CjcUp5MYO3Bgs4 ZejH7CQGSVWz15ivx9N4phr_bn1NYyxnBehSatFv4YIwHbH7UDRN4_Srl89XIoNwTH.OoGkBWNtc IfZZZM7iMLuBo7ARjBUZ0vsEwUbi05asA.Q7i5DvtLS8_gKutGg.FTYpXKWmxjG8XegvdAClzTaL EygUykGW43EPv0tWSp5p1WdihB_V3OoHqi.hwxvJQAeiK_LP.5VzY8SpGtPdreLTqtazbJP465T3 4_IUzh6C6I7M6Gsyr.N8.9.1uuQHVloJp.IinGhnhalvrb37zWjEu0uEAaNsU4Z3DUEfUbgDeYHj 63l5vlQBZYv87sSo.7YDiar419TqQ38qsPlkd7ZKyt78KVMQxkKRO.aNrO2F4HgwmLbanz6IFGHi _sxQrubruzD1dYbif2e9.aFeqSZahMnB7u0LiyyK18jHaJ4uNsaaPgZNdpe54LV.EXjaXPpZxXxs xPEf86OCcJsWAB5cS_x1.ke1_OPArs4MIGMdyvh_0o7JFamYwOV0XEt5W3ZQPL74pJwQL5oKDBg2 DHUqzuG9lrfjv4rc4XkoQRk8Rhl5ns36bifABFSOObmT3AIy_D2MAu6XZP2GOwouXtNrYVo9c0Rj q6DPfrLiGsD_xJ2bea3jDPYOj.BCJPKY.I5migAlKjnpfYMK_5FRu_h3zXEWIadYaViCW0SYh0ra yl0CsJzppk0d3SNX4iSHD7RxJOROAOe_Hj8ysqV.JwuTh_wg7Gu.XXzTt5Cj1JealfCYkazcB7M3 LqvBfJAXRtFCKKGe9tNZJzmUxkeg1Wm65LvCB2bSrtkee2a.gJfZf8I7UpGvvRR8gpvm16HjyyHI mkmtH5lvsfqdWaUEX.yc08fmZ8xINC6B.boPL7FtvYwQFfBEDrgRepavQGQA4DGti1l412ezHP3G ZEVmuzv0kN31bC5eb9B8RHskTvn_E6O50Fbt_75.lCqb6pGMWJSudcTNO49T08mgLnBc20YGnbHn 0Eys2rs_cdeGhtBeOSYD.ReqGDD_gygXRvfN48vfghEcBYfp19AKJBDMGYIy9GtKKdcVt.72FOnw 9SlHJQhVNVI1iDswOUqWSlekGy.BzM77stBd0LhW56OOo99tH2yyedlbsRBHATKsDLslwYUzwZtB FvX8p6gFU6NnUi8dH_xtQouIgwMa0.cbLSPu3WJyle2GZg_aP0ZmgDwtYbhfkf6sSECfXzd_unlh YZ1l9MU4kJ5ptkgH.1ecnDdTg6zjWHFkMwDCxGKOe4QHFL9b3lrt5bdW_DBgZkZ0366sljh.q_xI niAcdTsAOk.fSZQ6cmtZQcB6XoqupAKde1NnHv_FBzHyw1IPWEP_g95zNaZQ38Px97omQeQxMIFZ sfdKjzho8iv2AvwWSUoAKbj4WJ0xQvTXQzPl2d.fE22O9FVDMHnGhraWttyosLOBzjwpIGsHV9Sk rLeZn.P5Ct0E2BMuX7MesLc12BywwUNa_66Pb0Xzg961XjHoJpA7w1Oh2fcWtUTwxGCRFQGdK8Qk FD7fqo4XC9fFM6N.9SMGTqdN6p8etPykLv2u.MPzoHDLXDjwFSRl.rWEHvCEijhH3sC6eYApXSxY _tn8vQTDl4FSZApP4kN7PEMvrbFkVys4xNXK3sS1SIr7w3Mf_35uHoaIwuliBmgtVVee2sGzWN3o wzLB3nlcd83Ez2OMc2BoDZSaaHEGS8iWjZtKpFy1if5bGrN_QvCkQKcxmRL5xPzqpfF4fpniYD1U GIq4p0IPD2Ro1hnW96pu6ZIt0c9E1jbKaEPqSNUsk33cWOg-- X-Sonic-MF: Received: from sonic.gate.mail.ne1.yahoo.com by sonic306.consmr.mail.ne1.yahoo.com with HTTP; Wed, 24 Nov 2021 02:01:16 +0000 Received: by kubenode545.mail-prod1.omega.gq1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID efb3932afd4625ce53ab6c7e61a36211; Wed, 24 Nov 2021 02:01:12 +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, netfilter-devel@vger.kernel.org Subject: [PATCH v30 16/28] LSM: Use lsmcontext in security_secid_to_secctx Date: Tue, 23 Nov 2021 17:43:20 -0800 Message-Id: <20211124014332.36128-17-casey@schaufler-ca.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211124014332.36128-1-casey@schaufler-ca.com> References: <20211124014332.36128-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. Reviewed-by: Kees Cook Acked-by: Stephen Smalley Acked-by: Paul Moore 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 | 39 +++++++++++------------- 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 | 10 +++++-- 12 files changed, 81 insertions(+), 123 deletions(-) diff --git a/drivers/android/binder.c b/drivers/android/binder.c index de8f0661e8ec..caaee7f95514 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -2467,9 +2467,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 = { }; e = binder_transaction_log_add(&binder_transaction_log); e->debug_id = t_debug_id; @@ -2723,14 +2721,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 */ @@ -2757,24 +2755,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; @@ -2831,7 +2827,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)) { @@ -3114,10 +3110,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 0760cf52dbfd..7d9a45bc5bdb 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -598,7 +598,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); @@ -1459,7 +1459,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 c17ec23158c4..841123390d41 100644 --- a/kernel/audit.c +++ b/kernel/audit.c @@ -1190,9 +1190,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) @@ -1440,33 +1437,34 @@ 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 = { }; + int len = 0; + 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(sizeof(*sig_data) + len, GFP_KERNEL); + sig_data = kmalloc(sizeof(*sig_data) + 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); + len = context.len; + memcpy(sig_data->ctx, context.context, len); + security_release_secctx(&context); } audit_send_reply(skb, seq, AUDIT_SIGNAL_INFO, 0, 0, sig_data, sizeof(*sig_data) + len); kfree(sig_data); break; + } case AUDIT_TTY_GET: { struct audit_tty_status s; unsigned int t; @@ -2132,26 +2130,23 @@ 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_task_getsecid_subj(current, &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) goto error_path; 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 efd1a2a4216e..bdb368382e5d 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -1112,9 +1112,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); @@ -1125,13 +1123,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="); @@ -1344,7 +1341,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; @@ -1369,17 +1365,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); } } @@ -1534,20 +1528,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 dbba700fb151..47d1085e037e 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 de223234963d..0c3e1a8aaf2b 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; } @@ -658,15 +656,15 @@ static inline int ctnetlink_secctx_size(const struct nf_conn *ct) #ifdef CONFIG_NF_CONNTRACK_SECMARK int len, ret; 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 - * to use to create the secctx. */ - lsmblob_init(&blob, ct->secmark); - ret = security_secid_to_secctx(&blob, NULL, &len); + ret = security_secid_to_secctx(&blob, &context); if (ret) return 0; + len = context.len; + security_release_secctx(&context); + return nla_total_size(0) /* CTA_SECCTX */ + nla_total_size(sizeof(char) * len); /* CTA_SECCTX_NAME */ #else diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c index 3fcf44342b14..c8825e89a21e 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 5961a9b17f66..f19897b3cf39 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 7cb6f27c8cb2..596a75814fbf 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 5e6d088d94fb..989103ec9533 100644 --- a/security/security.c +++ b/security/security.c @@ -2327,18 +2327,22 @@ int security_ismaclabel(const char *name) } EXPORT_SYMBOL(security_ismaclabel); -int security_secid_to_secctx(struct lsmblob *blob, char **secdata, u32 *seclen) +int security_secid_to_secctx(struct lsmblob *blob, struct lsmcontext *cp) { struct security_hook_list *hp; int ilsm = lsm_task_ilsm(current); + 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) { + 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 Nov 24 01:43:22 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 12635785 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 E48D1C433F5 for ; Wed, 24 Nov 2021 02:03:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229774AbhKXCGl (ORCPT ); Tue, 23 Nov 2021 21:06:41 -0500 Received: from sonic306-28.consmr.mail.ne1.yahoo.com ([66.163.189.90]:44749 "EHLO sonic306-28.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229580AbhKXCGk (ORCPT ); Tue, 23 Nov 2021 21:06:40 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1637719411; bh=IIKa//ZfOf9ldI+2RZhwihcRPJzmFh5O4/PZDXiqrxo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject:Reply-To; b=PmEsScGDT56QiN+Jy0pLLGWnyKN/gxJNzyhhd6aK3mRYlCg73q0c9rwol/PA/5QNmZZrs8OwZfgaO37mdxg0V4fjz15kfxwtcKEJDh+75IDWTyrTBO3u6hs9kxW5Z0vRtPMUcWMQKBiYTU5IyFpBkiT/58d4bWNAxWwPYnST3qR1gN5OP2IN77JU9xK1JxhBF7LHzY1G2Y9e0HuyLBd1RZwklhIWJOGv4hRald+W0e5RrWL81YGjPUbxSLNUoCPqxS9ERupUW2f65ctbSz30DYdtloPxOi2dvPO9//HihtPZ2Z2l6sNx48LQGfh3ebYCgjDKsJZDPI9M91ojIjpkXA== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1637719411; bh=Kk3ubQbKAXNodGGFZb4TOQ/XxT7hCHClgdl+jbCiNKf=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=hraTilyCEzf3Xz1/kMyToHIaVcszJP3eHqQjv2dQJ6YIKwHp7DffGV2AMA4yQSYZ7QN5ETsT8VowS4tdEbkh3++cYGFS9LFR4YMKWydNPlURkN8JUvzQ+jT94yHJB6oVSIvoxE/flx1ElvjiAihZ50VXZBUGU8hQt2kYzyPsNSHvYIrck1Jzdy2Y/GuPcBbGU1d5WOoA/FbeN6c8rFumUQ9dOJcCsJBEy50sOCS1ka1SVvYPbn81UZRMm3wz96MFXTbF22EqqDqpjFVCkcB7iyO+Hez6fYOVc7wOIdrDnL1+xkKuwt/mhOnCXhX7PjojQk2L3iJrGLgtAY384u/ktA== X-YMail-OSG: xgUVGOkVM1nXHxEhPw3sY.j_OYRqsPJ_Huiuktw0vgRcbjLDak49Y_LL6lx24O0 TSqN1kqHycB3BvTPaG7wX3RoKQy3FMuo82MJNTaitTth_VmKUIYsXOEfWQnLy0YJCPUh8I35jHfd J4ZVfuNqjumX_KtVFVb6NMpG7e7nLkdJtE0bkbKG2xvCKGgMNI9OfVjCtlGx_7mA1KshGe7x9vUE K.5.8ozChTGi._V87HIYJBr6vD8njc5eX1z6w15rFSTgETPuC8wpzLZZK0DPIwsBSVd_GC4xjZNj W1T.Y2kYFr6BLkPf0H31S_cpiUE88HlzAv.5jmm.cmbye.z95.HPsV17ANiBMxD1CnlJEM_R.z1u 9csz7U54Fkqy9.7bdojv0i4hc8.EHOCvujS9.nnHngPkN7qdER1HoFMKCPjC_nAIKBYL3rWtpJyL zaEQEng0RQDUu0ViFd_EnqFDIHTHb8k_Wl.xvt4g.MrSbvLCVouSNkD9eeWA1szXUUlYuYs4Mj5z VpEOjsIn8PzkYEs6fM6X9MDeUUU_6gtKWn7P6rZfF975aK5EYOVXoxHXG56jGKZYGReRFK76C0h6 Y0A2QqWJwOqHfn_naJe3HYTCWlx7qpT.7F.zB1zQfMZ4_vNGdTiuMyG2Osu5xpzoxXo6gmBYtZCY R35Y0pUwhKp4IWxAimSx3Da7ol_yiQT6WNwitJz5gX8kv_DwtWLJnSBeYe0pSiccJJeD5HxjOEM4 1GdOYdV2BhRN1C1GgTBBx1JaFC7uHdgprTAbq7ndUWhugaF2ngRIISPP5zDFn_yB7DpoYvawXuuS .6IXhgOk.ANumooQJm3RQYwy9nrJb.lqWbNZ5BdsdTqUqO4o6I_0K6ko7wn39vQcJjN7HMJAZOBa QO5VtuIjSgmp2CkMpN2YJfP4KjOsjPqx2tehPWt3nAOEe0pTpDtqoW.UEZ5O0QS4XMx.oHmgkyxN PuC.UJbv6lC_8do6t5rCL.ZJJKyRfNtIJOVbo3PywFyQ98yHoCqEiaUnvw2zULc91TWJWrlMOhes CMWoEyc2tph.PfkOk54h215zmGpMdgvsWFbSM65cLtlv0yAhN8ze7_1ZTSlboKEYzGOGqBQ2PALM QqlO2WdmkocVV5eUd.e66rykwn_fggIuzayEN1zx8Np0V9ZXeVCqa8dFPO4TOKqqz6PavqCLmWyW M1fYpBAq4B1AOVUv1fex3xiRE798h_8PTSv2YpCLts3Q8WDLaiVnMqQ5cG3jj5PNUTXiaWyf8TW9 51POf8kr7xElrzvntsRoUTX31lU0C4r6GvPqKeGV5BWUw__FBSPtDf_j7K_pdPE9.BBgigfr45s1 bvOtgyGc46a.0AZxpeRBTSkwnbBkegjYTkqOzp0gsAYwuYcbgvDLVFEFKltqYBPw3Jk_2_RYfgkX ShIHrKXaj4TJr_hyHNfVwWNWCnX.2sH6ELK_Pmx4txwtq.bqofX_6SgzcSALI9_9w0NkgPP6WyMz cVfGlEF5M2s8qFu9g28jA_AT8pXN3ymunfJ45uAFS_tDg..0pfz46mv11CwtXFVH8RO3HfjrefeC gGKimdYrpfZ1FJaGVouF7VP_ZhOMMfixYrSZ.o.MLjae_0iAT3likas0bYQ5ucAfv8pqTgUE.YqP jYYzIKCGuT6FY0AZLhRRNEr1bg9mHbbj7dMNncrssaMCSrch7uaa1PefuGE9A2EnqI_sKGUx6tK4 or7plbTstSE90mr08RwTRe1p26WRHpzwHUvQXGm34vNKNEX6ratDTSNLkKUs1Mg9yzFhf9qAoiAF nSLbW5KotBRfBcz85mXrU0vA6xD7ZN_gxn9XTjfQWa.umOmAvR9u2ap8Qb0snHSNtMED.eV.YvyH UPERgDFVmMELHa5MNQAY4IxXBHj6.rw34KC9J8XPK_s1ZPt7xdqAh1LERUk3ZNURtf0XpsTmHRUm 0iMrqW6vI3ltV.EO4Xf1IVGVrLx6GV7d2KN8FYb.zPeqB7sBfknMNOS1xubHMgL2yASuqHf1zD_m Tk6dzvl_1uODOP2HIlavmCNclsLBn2QLsQ7TNE2USUWVzZxjZlrEpg3Uw_enI2kjkYfREXuG0QoH rkX3hhy5GqZyfsbx7nvh89jqVnEeC1sG.BD3Npdiuu5gliRGBQWH5nWmovj.cXaOmZKyxjP2hQlA 2K5sB8oeIZLyDvEp4iYRq8mPvWWkA1URTR9AM1E0GYsoewADPKf3Bnj1IW1HugA0PxSwYaznr_Yd TQuh8jPbULIdvMCz4KduFd4Q0gEIgDszYxtGt9afKFtsiIXZ.p7TDvwDQNG72D74O5A-- X-Sonic-MF: Received: from sonic.gate.mail.ne1.yahoo.com by sonic306.consmr.mail.ne1.yahoo.com with HTTP; Wed, 24 Nov 2021 02:03:31 +0000 Received: by kubenode514.mail-prod1.omega.bf1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID 6a5ec7ba15e43f08e83dd45ef02c9b3f; Wed, 24 Nov 2021 02:03:25 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, jmorris@namei.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org Cc: casey@schaufler-ca.com, linux-audit@redhat.com, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, paul@paul-moore.com, 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 v30 18/28] LSM: security_secid_to_secctx in netlink netfilter Date: Tue, 23 Nov 2021 17:43:22 -0800 Message-Id: <20211124014332.36128-19-casey@schaufler-ca.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211124014332.36128-1-casey@schaufler-ca.com> References: <20211124014332.36128-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 f19897b3cf39..69343275c54b 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; 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); @@ -602,7 +596,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) @@ -630,10 +625,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: @@ -641,10 +634,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 Nov 24 01:43:23 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 12635787 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 3CF7BC4332F for ; Wed, 24 Nov 2021 02:04:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239982AbhKXCHt (ORCPT ); Tue, 23 Nov 2021 21:07:49 -0500 Received: from sonic315-27.consmr.mail.ne1.yahoo.com ([66.163.190.153]:41171 "EHLO sonic315-27.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238872AbhKXCHs (ORCPT ); Tue, 23 Nov 2021 21:07:48 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1637719479; bh=GSurOhVzqUI/nNz8OcXYb0Mj9Kn5l034tUBurXhhR90=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject:Reply-To; b=Na1mWuXxqZ8cQ5OD9m5SFvSzYbwAgUMhLnRVu+Wf8YEX02nyE2WmAJ5PsLWEmsxPZ2hS0K/4FxzCAVCjQKFQbUqolqwJzdOmv0mJB6W6VqBNK/Ec9mvQ/wAnH9+6UoaTqO79t48zlLOaT9v8+mDEZPmal7qMiWrCXTL7evv3Dg9fgUl2gA4H9P3ysqmVeiU/aH39rcWtONmus4tO0kOOsx8rzzLFVeEfxmVl9U10YRnOS9vlK3l3DCBJitKFSPI9R8oxlKVmTPKn/Mbe8jzopxt1/qqbz3T1ia6uJaPNORgeYXuIuiLsG9uu9kqsIpXvcxMXPckJWuD5qIV5bi+pJQ== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1637719479; bh=FUqBDfTbRK9yH2Zkoh3DN2W1e2z5uhxYPhqjBODTXJ7=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=WvJ9ZgZC9QAca1bB7AxtOPXfZgE9TV8gQ5oWZPTUmMmcZTQaF51N+zgPIJs8tjgCsb+trktgEhxUgODj+canPastV5pcgzJelUd92VvgpUoDPjXVWRrWJr86/n6GqTjgg6KukiDXDeZNQbmTziJ0ai25CkdUy6NPMSSFBXza+d7GF3tHctsgEIBq+iq8NEmr8ztS/YPQquW4aht42X2Q+xNJd3KT2I0XLo8yrbeGvd8SAjtxRsIYhZo9Z9T8AltgnopJtJ3vDUT1xVqZ1ljNQfmPiC3VTC+FuP8tKKThI4m3zRkoRBAqLkkHAnxFHehXJrlhk7/wcKDrWMjd6Z57kQ== X-YMail-OSG: 7rpvYKwVM1nGyxjOi0wtE5ZPYlTo4jBVAie2oaAug4O8zHjASmyE.t29DC3mMgX Blsx5w616asMk.kxBkIFWvZ32CSRdYD5ObFy4iYG5MBMJN.r9V6y1Xc7ZOYIBuyQrWxnl_CS0Xk2 z8pOrTju1gb3iyV6ZYD2846WshI3Fxwy7lINgSm9jMJgrx3HvAkAUJ6pspDwpIuJVaA1U0W3.6eX j2GxXlKYBCt6x97Ubxbm42e9yd.rhMD6wLZFIsz.GpzDbvCi5yUsHY7CEXdJH04OTd28K7I4qXar r1Ys9bmIl8MZfbk_X.jcqq4RpX_CodlpKIvyA5oBwmMbnjQhyuWwYaZMMrEuDe0k2M8h65GldJ2. vZxF4VAbVJKF0EdJr_qpu40C7W6JBGm006grwBf7.w57zNi_biSvQx8qU4rHHCZ6BxfLb3Ci0Mdk m7eo2c8QlOmSb5SXP23EPLFNcsmdQIy4cR37ZrJJvDT_vVGfK8WU_8D4vLd6vwbnFDp8iizVFql4 MaRSodaIdaGgA1J1IPrM1jkNAJOgXISFleJAEyqgjzJnJn2UG__baxN_S.PqL2MxsBwODX4jRtco WnxuvLcfmd1DOEIZugvGBjriaddxYobJrbnYqLPk4hHRpMRpnu1jGJS8UxryE9OouKIjuenc0ha2 WKLfGsXy2SgvQWqtlJ3VYxIiIAV72BKGtmFlxRSdJJ2JbYYf1TYRoWXTTAtFagNot_EKWJUQdEI_ 4Wv.zKHVYsujXD.PGkdBGUrKc8WzHxITZt8tEdFY6u.Cd6pVK045xhPsa0tk9jptaTqDCT6rEnaj 6orCqULXH7oHyBueGwDI5.orXfGgyctKszT3EwcVGi30CGA1EGCzCvgbO0kpgUSI0dlPxU9IOmR3 EB87QM3xJi5UftHv1U47qIcaJyUPlUf3d8AttShWijF0YZd7krls7e6z4xR64c6oWcpt0AZvLBic SQN9t2JnkvCwwYA95onpng8mpM9lv05xfRwoTrFGoUF0gU_oAZdsAbiIrImUTWEnPFie4nnlH_m8 7z9.RdSJTLBRwquUEnn0qyAcVcOw9T3DyrvDpxxuYm2PGwMryF9QKeyERYTgMpUN9NddHAGEvDyI 9yLTqzYR4zIWpDNVgMAXEc.tRYGI8RvSwkTYb8m5ZbIo3MHClUVvNrIjvQrnWooJ8FH4UPtmATnh iQp28IMloX37kNKxfHPORgV42mb2V3lzfF8i4n_rTb8ExrHeLp5KcQbMFulLrS5D3YB_wORO8dbz 6sBpqdMBNad_ROIaC4NFemYhdBi3pA6GwupPosW10Nf_eeYYOHSd4BXnbSkIDhkLLklIbcEL3xid yr_fGV1XhXeJ4hYy4V82WGeKb_l7nXyn_jaHkeHaxsz5LgP3Y_CC9Z4sJpWIfeBjXLBJ_5EiZ.gE 03p16bq1sUosgeoo92_Q8VEKTGxMR0_NE3BWYvw09wwnE0CsGkIr5UXJdyC_HGvXGK0OiMuZ1ahw nRvPSnTqrVbnIeJ2aYaUOv37n3aoLOqSVIU4xJucODo7EbK9WRw79FuScrwDH4Z0ZQA8JC_ysfaW zFCQF_eDE5BxsrJD24tBS17t3zd5nApjTok06EhblZaPuQMwzIj.nvW1yyDKtIGk9hTMvKAU6qRX rKdEP28pz_71fff6QwefJ0BI0oMv4ugEfusm0dW2JDojkbiuFavmiSmwaTZ4q8TPzQIRaNUvzW7s lc10rSlUgRZQ8v3hc4gkU.pGmvv419xIgCtUOoCMFrnOOoyxNplxk1T.mkd91vbzEsTnKNAa6Gvl OmR3ssXM2ejkuiq5rZK08K8FR4uCYFpIbYgIiaINMaZi1reTurDXBAeFxDsWXmbdDMddMaNubEgY VtPdopLeAscj0FtYNVq..IOqO4QCe6ShJeq3OL9HWgxdupGA7wzCaHNVPJB7V_FVrgj3GxhtaF6u jCqxx.b09YpPHjphVKhvlW0w896E5X0wsGY2PPeCCh8cCxdnBuhHS3H9j15.4YgXH90i3E9Yb4kx noR56FGliPEKHo_nHUfWQBMcudvEq4.HtFsNB9sXOhB52kGQHqgtEjiU1PNGxaxC45cOIYoprEi5 QpIZEFs4QpNouwo9zurJosf1KG1.X3nTnFfEAGod9avENZF6evPbjlCbHKOM.zza.bNemu7N6YgT BaMGm7Syqg6JWUf.qRiF8rhdJ_h6u_ZxTeQ134GxXIZuhXF7srNi91wU2jlrMyWXIiQd9ASyTmQ1 d89B2A1zyzdlQgm7VShtmTw0l3CaVLdQLXcToLsdToCLEuBnb_.TCYwqVGkaC63SDgErHR7.gH99 eNTkvsgk79P3hjBcFztg- X-Sonic-MF: Received: from sonic.gate.mail.ne1.yahoo.com by sonic315.consmr.mail.ne1.yahoo.com with HTTP; Wed, 24 Nov 2021 02:04:39 +0000 Received: by kubenode551.mail-prod1.omega.gq1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID a5b8ecee55e7ad16fb8afdf394bffba9; Wed, 24 Nov 2021 02:04:33 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, jmorris@namei.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org Cc: casey@schaufler-ca.com, linux-audit@redhat.com, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, paul@paul-moore.com, sds@tycho.nsa.gov, linux-kernel@vger.kernel.org, Stephen Smalley , netdev@vger.kernel.org Subject: [PATCH v30 19/28] NET: Store LSM netlabel data in a lsmblob Date: Tue, 23 Nov 2021 17:43:23 -0800 Message-Id: <20211124014332.36128-20-casey@schaufler-ca.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211124014332.36128-1-casey@schaufler-ca.com> References: <20211124014332.36128-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 596a75814fbf..60e36324568f 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 824a6e4fb126..6f790d96594d 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -7056,7 +7056,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 66b813e15196..44fd5bc8ba71 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 1069ba7abf40..9832b5e5c9fd 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -3729,11 +3729,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) { /* @@ -4752,7 +4753,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;