From patchwork Wed Aug 26 14:52:30 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 1352003 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=schaufler-ca.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=yahoo.com header.i=@yahoo.com header.a=rsa-sha256 header.s=s2048 header.b=MXv1WAMt; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 4Bc8PX4rcZz9sVG for ; Thu, 27 Aug 2020 01:08:16 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727970AbgHZPIN (ORCPT ); Wed, 26 Aug 2020 11:08:13 -0400 Received: from sonic312-29.consmr.mail.ne1.yahoo.com ([66.163.191.210]:33048 "EHLO sonic312-29.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726873AbgHZPIM (ORCPT ); Wed, 26 Aug 2020 11:08:12 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1598454490; bh=yN3eueyIIik0iaafcLvxBpGYDxG1nxKL+aiZV3Os2k8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=MXv1WAMtgC12GVGPOJTmm7ZwSTDbgUNhT6hNFQTL8bFu+Lt3qZGbL21L+1cMMS7tlLy0Y6OSIvVeXtp0ho7opDi7cbQI3KH6+7GrcXWOpnSScBqmSB580nXdaOBpF5d7O3m2qDnOU4nQatyXY2SnFZyP5+8TjvfQhnWSVq5FJEwjeUZpUnhRlD1H1euVCUSBtNfIXErvhMN6PJSVJVz5peHakwXHgQWNRijBRNcItfSekfFZ7UcMDCzzbXE9KkaqxI/WI9dX147ORi0BiPWgQbHAe36L09Ws+S3C6J0voAW/hE0ppYfYTEHKMB3QVolw+U3OeRYKftgagztqArU4hg== X-YMail-OSG: TKMavaQVM1nrJYT5wR7tkBgyllUfSEcOH1E6nv7ytoakxLpS.TkRWJWXZ7d.RbH Qt8cGNGAjkbOCTgBw.7QnIhKbUjRE2ynAj3X4oCuEB88dlMFQ4hZe7mNyIlUljKfwMJGesbZTvU7 nP.NucR0SGxbcA3AbvdDfjwIqgupwoMMgEPW544h4ze0wMIPjdrUaUGc7AqlXjRMTRbokB.9ihvY 5PQ8lNf3whmMo0.uBqglKypkuZTLdCj0avjRpDnPVn5VfXZmXzGLCO3UdcydQ1OAAA_946nyfVfM Gb_KwCOnGBOvHb7tV2XtL08flBR_1BiD6fOTuJ9Ndphwan31P8pQBXQbWxO68Vx4JVOiPgkmYU86 QmCi0pYYnpR.ieJJYkx4rTUSoK4xdvewX8.CNXTf0e_2jgyXAiGkfqPHC.WPE4KV.iAip9P3aHvn Hr54IlkbyKxZPnyRjAog.ocUtyuAWPC5Aw8slmDN9Vb4sgva8q0LKUD1CpP7IbzggN.64fRzSxIG gUql1TIECGnluNbEiXAvY_4doFG7HmYyAP.aSVi6lzfwDpLlBcSp8j04vk0F2u1tbk7it_g_fd8S iidZ6L6.AVfg1KVdUfONSDDpCTBL5XAhaqL7d0Cnr.dGRSJfz2kppzWc6OLdUtSKD0DdHoGIjO2A 6gdtPBJV0RwM8t0HuPopyLRAz4lhO58ji7I7htTn0EVSGdgviWAE8MVI7ngoguKGkt11I0.LSoFu U2WbEe0O2GC2kktnRcf06IW3oDNORHNpqgcSAqR99WV56FG0y44h0XSblGFaTlTB6sKOfTs.m9QP AUZXC18cTeV9mENyxsknN_Ke4Qa_0ZS0VDUouxBVlm3mUazM9lNTDv6iSdUNF.pP_m4Ze1ilm.KW uCwIVX_kNY1lpRrUgk.isJQ7Mxz.byCWKRGLccLi7Gbi0eL3Ghg0O3nmOBnT.7HDCQzpmhswskc7 dXFQl9nYmG2EtgmfCz4POGhZ4dpDOiMeo5gf8KwVvXIZLhHT2tMnzF.dhE9ZCLjdAVvQgEwJVzCM rYjrFxXLWbPJHYZ0VaxnAcwRGYh_okmHuNVWJvgEVqHEjCT9Aod9oGjC_P1bkD7vzrML7caXwPXQ btVe4II0HvbCHjgVxTtTPivqb3VYs684NT2bzn9TZ4DulrwAlIP.EU5K1NVn_9TZrymyOjzC1P60 5TuMqGtQENJS7q40DgkYEDfzn9KhtpYdtyAztIVhqWlEiHybOHpE1byzsaZ4nvOokvFlOuzGZtLU _ORLL9p02gT0Cc6IrOfvaIVUqnVFiKkoOtvmOht5MAGqysRW3FXgYKUEx2Q9DR6qwQ..P6hNOQkK 5t8zv3JG6GQAqWnbGRdI.eD8smQGE0izAoc59puALHYEoMKovjUwXLqEsHa10H6Ox5QA1HPwtsk2 W3DzOLJJLCSQUDc8y2k6s.15G97snXYMBIJ7uqY07t3uJT13ue_tRYRwLcZRARerJ2aAngea58g0 y3uFFtSYXpviqXsOTyIauBTlgx3DPJQHLrSqFGy8Vfkw2YysDIWnyYdRBO_.wkE23gOAYYZCtAMQ iX05B1vUGzK3Enow- Received: from sonic.gate.mail.ne1.yahoo.com by sonic312.consmr.mail.ne1.yahoo.com with HTTP; Wed, 26 Aug 2020 15:08:10 +0000 Received: by smtp416.mail.ne1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID 3ff895580a9dbc79776f995de0655309; Wed, 26 Aug 2020 15:08:06 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, jmorris@namei.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org Cc: casey@schaufler-ca.com, linux-audit@redhat.com, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, paul@paul-moore.com, sds@tycho.nsa.gov, netdev@vger.kernel.org Subject: [PATCH v20 06/23] LSM: Use lsmblob in security_secctx_to_secid Date: Wed, 26 Aug 2020 07:52:30 -0700 Message-Id: <20200826145247.10029-7-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200826145247.10029-1-casey@schaufler-ca.com> References: <20200826145247.10029-1-casey@schaufler-ca.com> MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Change security_secctx_to_secid() to fill in a lsmblob instead of a u32 secid. Multiple LSMs may be able to interpret the string, and this allows for setting whichever secid is appropriate. Change security_secmark_relabel_packet() to use a lsmblob instead of a u32 secid. In some other cases there is scaffolding where interfaces have yet to be converted. Reviewed-by: Kees Cook Signed-off-by: Casey Schaufler Cc: netdev@vger.kernel.org Acked-by: Paul Moore --- include/linux/security.h | 30 +++++++++++++++++++++++---- include/net/scm.h | 7 +++++-- kernel/cred.c | 4 +--- net/ipv4/ip_sockglue.c | 6 ++++-- net/netfilter/nft_meta.c | 18 +++++++++------- net/netfilter/xt_SECMARK.c | 9 ++++++-- net/netlabel/netlabel_unlabeled.c | 23 +++++++++++++-------- security/security.c | 34 ++++++++++++++++++++++++++----- 8 files changed, 98 insertions(+), 33 deletions(-) diff --git a/include/linux/security.h b/include/linux/security.h index ae623b89cdf4..f8770c228356 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -190,6 +190,27 @@ static inline bool lsmblob_equal(struct lsmblob *bloba, struct lsmblob *blobb) return !memcmp(bloba, blobb, sizeof(*bloba)); } +/** + * 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); @@ -503,7 +524,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); @@ -1322,7 +1344,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; } @@ -1412,7 +1434,7 @@ void security_inet_csk_clone(struct sock *newsk, const struct request_sock *req); void security_inet_conn_established(struct sock *sk, struct sk_buff *skb); -int security_secmark_relabel_packet(u32 secid); +int security_secmark_relabel_packet(struct lsmblob *blob); void security_secmark_refcount_inc(void); void security_secmark_refcount_dec(void); int security_tun_dev_alloc_security(void **security); @@ -1585,7 +1607,7 @@ static inline void security_inet_conn_established(struct sock *sk, { } -static inline int security_secmark_relabel_packet(u32 secid) +static inline int security_secmark_relabel_packet(struct lsmblob *blob) { return 0; } diff --git a/include/net/scm.h b/include/net/scm.h index e2e71c4bf9d0..c09f2dfeec88 100644 --- a/include/net/scm.h +++ b/include/net/scm.h @@ -97,8 +97,11 @@ static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct sc int err; if (test_bit(SOCK_PASSSEC, &sock->flags)) { - /* Scaffolding - it has to be element 0 for now */ - err = security_secid_to_secctx(scm->lsmblob.secid[0], + /* There can currently be only one value in the lsmblob, + * so getting it from lsmblob_value is appropriate until + * security_secid_to_secctx() is converted to taking a + * lsmblob directly. */ + err = security_secid_to_secctx(lsmblob_value(&scm->lsmblob), &secdata, &seclen); if (!err) { diff --git a/kernel/cred.c b/kernel/cred.c index 22e0e7cbefde..848306c7d823 100644 --- a/kernel/cred.c +++ b/kernel/cred.c @@ -757,14 +757,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/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c index 551dfbc717e9..c568574abfae 100644 --- a/net/ipv4/ip_sockglue.c +++ b/net/ipv4/ip_sockglue.c @@ -139,8 +139,10 @@ static void ip_cmsg_recv_security(struct msghdr *msg, struct sk_buff *skb) if (err) return; - /* Scaffolding - it has to be element 0 */ - err = security_secid_to_secctx(lb.secid[0], &secdata, &seclen); + /* There can only be one secid in the lsmblob at this point, + * so getting it using lsmblob_value() is sufficient until + * security_secid_to_secctx() is changed to use a lsmblob */ + err = security_secid_to_secctx(lsmblob_value(&lb), &secdata, &seclen); if (err) return; diff --git a/net/netfilter/nft_meta.c b/net/netfilter/nft_meta.c index 7bc6537f3ccb..7db487d93618 100644 --- a/net/netfilter/nft_meta.c +++ b/net/netfilter/nft_meta.c @@ -801,7 +801,7 @@ struct nft_expr_type nft_meta_type __read_mostly = { #ifdef CONFIG_NETWORK_SECMARK struct nft_secmark { - u32 secid; + struct lsmblob lsmdata; char *ctx; }; @@ -811,21 +811,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(&blob); if (err) return err; - priv->secid = tmp_secid; + priv->lsmdata = blob; return 0; } @@ -835,7 +835,11 @@ static void nft_secmark_obj_eval(struct nft_object *obj, struct nft_regs *regs, const struct nft_secmark *priv = nft_obj_data(obj); struct sk_buff *skb = pkt->skb; - skb->secmark = priv->secid; + /* It is not possible for more than one secid to be set in + * the lsmblob structure because it is set using + * security_secctx_to_secid(). Any secid that is set must therefore + * be the one that should go in the secmark. */ + skb->secmark = lsmblob_value(&priv->lsmdata); } static int nft_secmark_obj_init(const struct nft_ctx *ctx, diff --git a/net/netfilter/xt_SECMARK.c b/net/netfilter/xt_SECMARK.c index 75625d13e976..5a268707eeda 100644 --- a/net/netfilter/xt_SECMARK.c +++ b/net/netfilter/xt_SECMARK.c @@ -43,13 +43,14 @@ secmark_tg(struct sk_buff *skb, const struct xt_action_param *par) static int checkentry_lsm(struct xt_secmark_target_info *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", @@ -57,13 +58,17 @@ static int checkentry_lsm(struct xt_secmark_target_info *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); return -ENOENT; } - err = security_secmark_relabel_packet(info->secid); + err = security_secmark_relabel_packet(&blob); if (err) { pr_info_ratelimited("unable to obtain relabeling permission\n"); return err; diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c index 77bb1bb22c3b..8948557eaebb 100644 --- a/net/netlabel/netlabel_unlabeled.c +++ b/net/netlabel/netlabel_unlabeled.c @@ -882,7 +882,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 @@ -906,13 +906,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); } /** @@ -933,7 +938,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 @@ -955,13 +960,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 c42873876954..5c2ed1db0658 100644 --- a/security/security.c +++ b/security/security.c @@ -2065,10 +2065,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); @@ -2301,9 +2313,21 @@ void security_inet_conn_established(struct sock *sk, } EXPORT_SYMBOL(security_inet_conn_established); -int security_secmark_relabel_packet(u32 secid) +int security_secmark_relabel_packet(struct lsmblob *blob) { - return call_int_hook(secmark_relabel_packet, 0, secid); + struct security_hook_list *hp; + int rc = 0; + + hlist_for_each_entry(hp, &security_hook_heads.secmark_relabel_packet, + list) { + if (WARN_ON(hp->lsmid->slot < 0 || hp->lsmid->slot >= lsm_slot)) + continue; + rc = hp->hook.secmark_relabel_packet( + blob->secid[hp->lsmid->slot]); + if (rc != 0) + break; + } + return rc; } EXPORT_SYMBOL(security_secmark_relabel_packet); From patchwork Wed Aug 26 14:52:38 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 1352010 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=schaufler-ca.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=yahoo.com header.i=@yahoo.com header.a=rsa-sha256 header.s=s2048 header.b=YV+3dwkq; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 4Bc8c73xktz9sVm for ; Thu, 27 Aug 2020 01:17:27 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727945AbgHZPRX (ORCPT ); Wed, 26 Aug 2020 11:17:23 -0400 Received: from sonic302-27.consmr.mail.ne1.yahoo.com ([66.163.186.153]:39387 "EHLO sonic302-27.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728075AbgHZPRH (ORCPT ); Wed, 26 Aug 2020 11:17:07 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1598455016; bh=/4qQ3kWpoJzQ+9NCC1QWeIokAaa1N28W0MUomHOZcbQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=YV+3dwkqwY14BUXBu+isW5CAOQ4dvi4jwnhp3jQnaweoU4BnYUSMsn8G1BKJHuoYlcIiF+dxX3opstjxnSHtMIQwlNFZa8oF2ql7yc7kcIjH+XPo523ggPojELSzWoF6qrYoBRBrKfx1nfTA3KEPQAmqLhjn2KkdO+EdoS90xtj4N9xji6IrpHF7K8isvHrKaUdJAam1IJEp3xgq+PwLcMNOrq27ZNT2aosfrV+o1Im9litF54FV2rM/cQOBPCkb8BRIU4AGffR8tp+N4OAeDvotbygqaJbXUtx0tUJutmMUWpFwjuoRPp8dXmTc1GF3q8PJgV6rJXfw+s5SyNfeHA== X-YMail-OSG: CHeUtkEVM1me28u61fI0pAAJj1130gr.F41soVZbOQSpdLCfepo1e4lAXt5osHG mVkcf7py6uj9LwNcHz.OOs96dbMNHCRyXcVvmxWDf5lj2j5hJX549fqSIRZ_4cSTAY1FhV.SzBsM yJw1vVfQr_EkOnqI_9BjR3aK9YcqUczYerI74x6R7m4CGOzNnecGCHQjU4vZ4B6Pux2SsM3wUGFF yC12GAkdkZe.LGcweRQrrWELfBTXgzKKkGDbOQ3QIzSsmVV0KYOqAlWpnjFtMGN_5n4xN75RAflI H7D15tfCWv7eyeWtwUxgJrpZV.iYpfKpbfcFioAjJZHepNH7wgWjkjRm74r.Njyn0gSYZhEdcOAC SiHsbt25PQOvA9grsGHwYvXvdNm.84lW7.2_3QcER2RIVmBvU8jj5lBZBD3clJYcwiCJLF5WC3QB Y8lr_ovTKWcFEFCip.yXAeTTs.Q4HDfSBrncWTHJ0GBdx1YJI0tdTJW4OV1tsHF5dSuiSgpD5GG2 pG.K6Wwy.lVeTNgnODlKW7183xiZwItiCGWS4wysJeq5l1kQqr3By5mBMBttaH5FphTDsMOZShRN 89ZcoELCAU7mif3jNEU2LiBFReyd1FaYsFtjO5jO7WJD9eHHkCrp4bgDHFdtVIy.cm8I_C9Xt5MK swzFRPXdKxJScKfVcbvAm8Qzr1Q_ECyJy49KqqT3acWc7zD831t1tH5i4QZjuMwE_y0TAHMeF0XA 4XApAuCN4fbeCdjLmahGNkzohV1C1YuGeSp504OVJTZpSRk8r4Eo1UPWSWUFoXLkarkjt0cvAarM goGp8nfsplb40eFdoZ9t.AW5hAqrJkxQ2.dYReMlO86AagJRMJnZZFCqinK1MOIlLty543vvFJUh u0WtZJ5sBjD2xImCsbHhLqpr3n2ShA3S2GFHx3.2iHI8W1QxWjcq0gIeFkiGTONmuylp.sMGRtE0 dVgDp1xZiDlkGvy1TyAjEvJV4WDWGMNz7JHfKXxAiLxerdEBxYfsUn3SiPvVf5MluO2.ItSgcYRC 8pB6wvGcqfL.s5Ur5fNhsX4DMKtEfbEnwohvzR_dIYinZVJfUJq69JEpCeiDfyMghCnD6G4TmNHE AtT.GWPxM6rb76I2GGCPAvzcPY2DqM1WgM8wvqLugu9Cku5DmodvHxGrHdc64HLWT.MBUghutgvL uGvVruy6WxFczKM2OwytiBCd0ncLduhOQHpxmlUiuOCO7X31Nlpixei1UtYK2c9Cfx6RAgHj6Z2i fDTBdd50tZFCPSLvxUwldtCu8HmxNlnG49j9PlO.gS9lGT43NPVJw92A_29DoKymx6CGgpls.HS1 Q2yVYuOJHkysdnA5g6z6wDrOQ5NzuILSYlyqAnMd0s1gJ9NfUImC9SP85E_KmZYa8R16Xy8U.Deb VDI0dHjcHGo9up0YqL88vWzr1TCAOXTsW9l0nTW_d8_J1EFf2hOMo12suX5xO1rur3TMF7i7VByV bVWgtX_tPsvfqMLr.vHk4CWn2dffQjVFFPcv9NSd5r_8O2KzJnMRPN2jif8BYNtrEk13fMRHsDBS wcB7SW1p16cJCFrCwKBHjYCABO7mm.g-- Received: from sonic.gate.mail.ne1.yahoo.com by sonic302.consmr.mail.ne1.yahoo.com with HTTP; Wed, 26 Aug 2020 15:16:56 +0000 Received: by smtp404.mail.gq1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID 0d658eff16f1d68935fd759b76f93396; Wed, 26 Aug 2020 15:16:54 +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-integrity@vger.kernel.org, netdev@vger.kernel.org Subject: [PATCH v20 14/23] LSM: Ensure the correct LSM context releaser Date: Wed, 26 Aug 2020 07:52:38 -0700 Message-Id: <20200826145247.10029-15-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200826145247.10029-1-casey@schaufler-ca.com> References: <20200826145247.10029-1-casey@schaufler-ca.com> MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Add a new lsmcontext data structure to hold all the information about a "security context", including the string, its size and which LSM allocated the string. The allocation information is necessary because LSMs have different policies regarding the lifecycle of these strings. SELinux allocates and destroys them on each use, whereas Smack provides a pointer to an entry in a list that never goes away. Reviewed-by: Kees Cook Reviewed-by: John Johansen Acked-by: Stephen Smalley Signed-off-by: Casey Schaufler Cc: linux-integrity@vger.kernel.org Cc: netdev@vger.kernel.org Acked-by: Paul Moore --- 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 1d9b0e385cd0..b0d9e9fad07a 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -2861,6 +2861,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; @@ -3163,7 +3164,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; @@ -3496,8 +3498,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 3a733ac33d9b..27932f6b4cd6 100644 --- a/fs/ceph/xattr.c +++ b/fs/ceph/xattr.c @@ -1272,12 +1272,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 dbd01548335b..079634557ad4 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -131,8 +131,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 259d5ad0e3f4..0fc505392728 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -2717,6 +2717,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 @@ -3228,8 +3229,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 7de2b4e62f55..54d5f74d3565 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -131,6 +131,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 * @@ -526,7 +557,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); @@ -1353,7 +1384,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 31ae605fcc0a..30ba801c91bd 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; char *secdata; u32 seclen; int err; @@ -102,7 +103,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 88b55b42756e..32be5b4cc068 100644 --- a/kernel/audit.c +++ b/kernel/audit.c @@ -1193,6 +1193,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) @@ -1450,15 +1451,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); @@ -2130,6 +2134,7 @@ int audit_log_task_context(struct audit_buffer *ab) unsigned len; int error; struct lsmblob blob; + struct lsmcontext scaff; /* scaffolding */ security_task_getsecid(current, &blob); if (!lsmblob_is_set(&blob)) @@ -2143,7 +2148,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 b15222181700..2b06171bedeb 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -998,6 +998,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; @@ -1015,7 +1016,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="); @@ -1228,6 +1230,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; @@ -1261,7 +1264,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) { @@ -1407,6 +1411,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)) { @@ -1415,7 +1420,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 c235c57d7469..f2ee29d55ad6 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; @@ -144,7 +145,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 380b660d0d39..1c45ca8c3c21 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -334,6 +334,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 @@ -354,7 +355,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 18376e68fea6..87a70159ecc9 100644 --- a/net/netfilter/nf_conntrack_standalone.c +++ b/net/netfilter/nf_conntrack_standalone.c @@ -176,6 +176,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); @@ -184,7 +185,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 7b00dc833a31..d175477d68cc 100644 --- a/net/netfilter/nfnetlink_queue.c +++ b/net/netfilter/nfnetlink_queue.c @@ -398,6 +398,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; @@ -628,8 +629,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: @@ -637,8 +640,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 f4a6204f4205..5785e6dcf54b 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; @@ -509,7 +513,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); @@ -546,6 +552,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; @@ -576,7 +583,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); @@ -1095,6 +1103,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; @@ -1165,7 +1174,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 e1c9f87db64b..a6d0b6851a66 100644 --- a/security/security.c +++ b/security/security.c @@ -2227,16 +2227,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 display = lsm_task_display(current); hlist_for_each_entry(hp, &security_hook_heads.release_secctx, list) - if (display == LSMBLOB_INVALID || display == 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 Aug 26 14:52:39 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 1352011 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=schaufler-ca.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=yahoo.com header.i=@yahoo.com header.a=rsa-sha256 header.s=s2048 header.b=I9bKumLl; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 4Bc8d13ZNJz9sVQ for ; Thu, 27 Aug 2020 01:18:13 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727779AbgHZPSI (ORCPT ); Wed, 26 Aug 2020 11:18:08 -0400 Received: from sonic312-29.consmr.mail.ne1.yahoo.com ([66.163.191.210]:39212 "EHLO sonic312-29.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727883AbgHZPSE (ORCPT ); Wed, 26 Aug 2020 11:18:04 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1598455082; bh=Wt7aXwBOdVBSCTAjGCztyM7JD6qGvOiN0lBhuN3Z4Iw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=I9bKumLlbWslsEmgJn8BnpknckX4Hs8qcs3b2IgKuSHhUrRKV6NZ6hdDSb/Ry9Z/wDYQs0bOc2UNCFwh006nhG2GuWDr5LvwzeuZ1E/ecmg+n7I4EJjGze4K1EBpWwY1y6f/e9sguptZELaB9YzGJ5geCCL26Ualnp7CpFGkObYqLVCxjIkb8uFrlWfBJLzIN5yb3S7e0AN/+Lu4NjeclqK8XSSZW/+lzUOsWaNIE8up+OeiGz+KTLcKz+2BtcC4Bj+VO0iqqmnk7AJPIgqkZHQSDCsk9KHycch0CBiDDfKXsGsYBGVjSc/+OR/5oi/BzP9nw1RCLD6JS+EXIXYbcw== X-YMail-OSG: qjK2pzYVM1mc875ti58TtjLbOuW.ohqaWkYXaiLveIDHW9mYGn6qPlfa59emtGG UgBHu9zDG7fXVaacXqEc004pKeaa9XYvtfL2YIxNUofrFOGnl92rfOeq9DqcU73K1IX7V1GecFVR VZaXcPLH6zXVh34iSmcgVMENvMV1j92X2RDv6sxq6hDUXKpvyYp.J7wSA8MGGLRRzU3jY5Bz_exx CxpWaDtcfjABuUrYVTUyluRnpH6tw5VLZg.B1rGp_6vdFmrAu5KwM54_ANJWD5NjGCrZAaSAik5d _JV5cnOl9SUOXS_jZh7r39lasCGq9RpzvYhy_xlfKQgU56JJUErQmBrjXIbRPRN4nD2.plo6IuIW gKKyNBltAIWx2JaF4Rs_j4owytfpCXCpjv0kV_AZPygq4sNjjs7jTvUn0LQmuV4GPhXeMcdLiGNg h_Zz_H5xQ6nhgAiR0JCIj1csHRT6zAVhzjleGLe6Rfa8yHZQChnDPixKgy7QHEn3cEl3rOnUNBqm yxP9Cv5HAAaNLALEfZtxRHllCGpvfzhihEuXZqGRVwSoBHft5nvvKt_dwnMhAAF9xdnLpPsoYJDw PSLfsNIGFbcybjkefKZslcLBA5nPuc1GELfM25Qz0Sa9EFTdQcbI1EXXiJY7IGWn2f3RNkG5vZVa .gV8m.kzM6rCx3G9uZrJ8NcOyFHfL3_16RIBy2RxfCdkgXrMQ6zaHsnbecW4AOZeicT0JGOAme1n Cj8fWpnJTbauDErbHP.lzaCzHAZD.1nvIG8HdCjvQh.4RH9kODd4jm8rJ.rGEEsi6oS7kPEuAvGU emSvtFsOQc4j0F7HEy7fPiBkHFZRQ4N8zgEP6uCFGs9SNtly63kLDOAXlPjrQXCOqvjQSZymXOY8 J6iKxtSOeA3NTJn.WmEHKQiG9lpoz_egiNM0Y3M4NQLk0oWAsg58fa3xYJmRNS8bXnvQj1d96h5o vTQ5fCXvnwLvVr0qxMx3kcDAeXdMmMd7O80YgL_0oynv4G46JfNzpo3ewLpr.oud27ava8pJLF3A sxpXGF14OLHreAuXrsfku2hTrDDAnDRAgmUBZpbhhzX3JGU49lpK69dosqjzfXich4In9mCd0gsC wfjZTm6uDW23oPZFEZUWV8Aa63XtEISvZxxSH8V9yq51pqZ2tGQPCUwEbWBMJjTn9uwyBv4HgvVQ ZPpQOGx3Cs0_WRc5.ldou1U2lsOQ2aQAUHhar53o_D.PPitA.bFl2EiQZ3MdDxYhuFU_qBLybfRR QPOV2fj44rR6v73aI4CCflNT0t_QuDxX.I0ZfDkU6j5pcMlaWHF3UB6Ofzsd3q6bXgybudBOq_sn qdF7Xf6v2OTX40gmwOjgynMxSKJ2Vpx98Zv9gAZwY1qz4pbCpxPb8b1SOeCmqJMDiA7EO_SFgLR6 bgc8Mepx6Nz5eah.CghL6DJ.3wXsF_pgixcWZ6PpxXRcGRVsXivkLHQAuAuItS_K4jAchkWTo0Tn m7_oAyxjCPb7Is6ON21xD2r8qcoC2n2n_s7KLrwUnN98.yjMsZq52f.q.LFhiVl5.mnV3Cfj9Y17 IR66hAmkpxAq2V81qJhm_Js92GH.L077a7BkMR5jkp4sh Received: from sonic.gate.mail.ne1.yahoo.com by sonic312.consmr.mail.ne1.yahoo.com with HTTP; Wed, 26 Aug 2020 15:18:02 +0000 Received: by smtp425.mail.ne1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID 3b60f078be79fd822b39a8aff8f9a87b; Wed, 26 Aug 2020 15:18:00 +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, netdev@vger.kernel.org Subject: [PATCH v20 15/23] LSM: Use lsmcontext in security_secid_to_secctx Date: Wed, 26 Aug 2020 07:52:39 -0700 Message-Id: <20200826145247.10029-16-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200826145247.10029-1-casey@schaufler-ca.com> References: <20200826145247.10029-1-casey@schaufler-ca.com> MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Replace the (secctx,seclen) pointer pair with a single lsmcontext pointer to allow return of the LSM identifier along with the context and context length. This allows security_release_secctx() to know how to release the context. Callers have been modified to use or save the returned data from the new structure. Reviewed-by: Kees Cook Acked-by: Stephen Smalley Acked-by: Paul Moore Signed-off-by: Casey Schaufler Cc: netdev@vger.kernel.org --- drivers/android/binder.c | 26 +++++++--------- include/linux/security.h | 4 +-- include/net/scm.h | 10 ++----- kernel/audit.c | 39 +++++++++++------------- kernel/auditsc.c | 31 +++++++------------ net/ipv4/ip_sockglue.c | 7 ++--- 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, 80 insertions(+), 124 deletions(-) diff --git a/drivers/android/binder.c b/drivers/android/binder.c index b0d9e9fad07a..0bde1b96680e 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -2859,9 +2859,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; @@ -3115,14 +3113,14 @@ static void binder_transaction(struct binder_proc *proc, size_t added_size; security_task_getsecid(proc->tsk, &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 */ @@ -3149,24 +3147,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; @@ -3222,7 +3218,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)) { @@ -3498,10 +3494,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 54d5f74d3565..de6b44751dee 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -554,7 +554,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); @@ -1372,7 +1372,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 30ba801c91bd..4a6ad8caf423 100644 --- a/include/net/scm.h +++ b/include/net/scm.h @@ -93,18 +93,14 @@ static __inline__ int scm_send(struct socket *sock, struct msghdr *msg, static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm) { struct lsmcontext context; - char *secdata; - u32 seclen; int err; if (test_bit(SOCK_PASSSEC, &sock->flags)) { - err = security_secid_to_secctx(&scm->lsmblob, &secdata, - &seclen); + err = security_secid_to_secctx(&scm->lsmblob, &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 32be5b4cc068..594b42fc88ff 100644 --- a/kernel/audit.c +++ b/kernel/audit.c @@ -1191,9 +1191,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) @@ -1441,33 +1438,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; @@ -2130,26 +2128,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(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 2b06171bedeb..4af5861bcb9a 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -998,9 +998,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); @@ -1011,13 +1009,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="); @@ -1230,7 +1227,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; @@ -1254,17 +1250,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); } } @@ -1408,20 +1402,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 f2ee29d55ad6..58bf1f3532ae 100644 --- a/net/ipv4/ip_sockglue.c +++ b/net/ipv4/ip_sockglue.c @@ -132,20 +132,17 @@ static void ip_cmsg_recv_security(struct msghdr *msg, struct sk_buff *skb) { struct lsmcontext context; struct lsmblob lb; - char *secdata; - u32 seclen; int err; err = security_socket_getpeersec_dgram(NULL, skb, &lb); if (err) return; - 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 1c45ca8c3c21..e38b5182e301 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -331,8 +331,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; @@ -340,7 +339,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; @@ -349,13 +348,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; } @@ -655,15 +653,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 87a70159ecc9..71bec249d23b 100644 --- a/net/netfilter/nf_conntrack_standalone.c +++ b/net/netfilter/nf_conntrack_standalone.c @@ -173,19 +173,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 d175477d68cc..d3f8e808c5d3 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 5785e6dcf54b..cf4c56beb3ec 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); @@ -510,11 +503,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); @@ -553,8 +544,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); @@ -580,10 +569,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); @@ -1106,8 +1094,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, @@ -1167,15 +1153,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 a6d0b6851a66..862f0bc2f114 100644 --- a/security/security.c +++ b/security/security.c @@ -2191,18 +2191,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 display = lsm_task_display(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 (display == LSMBLOB_INVALID || display == hp->lsmid->slot) + if (display == LSMBLOB_INVALID || display == 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 Aug 26 14:52:41 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 1352019 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=schaufler-ca.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=yahoo.com header.i=@yahoo.com header.a=rsa-sha256 header.s=s2048 header.b=RgcM/Azl; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 4Bc8gh2vNjz9sVQ for ; Thu, 27 Aug 2020 01:20:32 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728069AbgHZPUW (ORCPT ); Wed, 26 Aug 2020 11:20:22 -0400 Received: from sonic312-29.consmr.mail.ne1.yahoo.com ([66.163.191.210]:41077 "EHLO sonic312-29.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727991AbgHZPUQ (ORCPT ); Wed, 26 Aug 2020 11:20:16 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1598455215; bh=qd7sr8JC2sP3QmLhn76nKiaVYv/GIrllEFl1X7JnYN8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=RgcM/AzlFDLDuxtNrQ2V8vN//bNiyOo9dzHver6pjmHosJXlFfhXrk8OE3r9mvhyb3DRiDRAwoc3K8kM0eVKcgR0ta2L3yixL9NGial3jUcJr8d2Ur3d0eskElsQd/QTQ2nGQVmUhEAuL/t4kBZeLPW/IJjuurVacoRuHjo1FaITnZYvX1vVeq4YesKnFs77cFQ623hvh5Hb5tjeSciZX4LeRsubtsAeOvIKxueFg/eIMTPt0BRwI74cILvGWc5IHpgcdUbsveWAJYhUeF5oNdKEiCtSWghLao0IbygbqAO5J8xHzNzrQipCyvmrY2Rh3fsijc3iNh1f+JlcLtC+xw== X-YMail-OSG: GajDSr0VM1kZ0OF65FN7B17KCqyzINJ4OFknWUfu5MG0eIPIrtueVQn902HZfWX QRJ_USigcC0QuaOB4.9_.OGgrqfJv4aRa1FT86JHEhSiY48fnL19KkrQBXJ.ablryAisaL6Qx2w3 vRU8MeZhJLQyjGGlSW994kMY0LZRhnPFn71Ov1yTu06w8I__DCTRphlSRUnwHSVod_h.0WrGaU5u eonjvKl.yAtO_uF8lAmKRTTU3HN4dwJ6ZsHV7gapLUiRGmy0FsG3T5p4CkdgZHxE.MaxelwFxp4P lvbYfQstls_rOTY4SnSgwy92mPRAYRjKVv5jNwHuIxAoJoSXLXkKPBHm.CKLK1IcVrZzHsWi_F9K NpP4qFP70mqNP5dU_I_dTIokfBQzoHck7sergVs26m23rV2p9T.WbNbyafhjTJ697ZIHtWt.F4ec cGE5VYk9zncd6g1sSMpPzp_J54VSmZ0Wxpny9GGLdPyw0t18fin2k7DMoDBE.IEe83iEEgDvQ3wS ZQfiGkuBsKf4_J6IK850pLIzCeUmaJ24_cEcY8IL.ksmGfBQpjbwV8KdoQvK_LHHI7OYo6X.PKoj 3tRerT31Av87tkyz3pctiJZDFLfvF.2Qy529wWldcYtAcDhf0TfhSm1d4cya7SEZF3u15e_ZmgCj HnChLUAZOrLX3ymj5yfnNhyiBeutn4kkfz7i20RpWFT1ucnqG5nOh2.vWQvH6LMFieudhH5hsCfb D8cl1SGI7A5e_z9YjGWQ5mHzMW8g7VLkVhGqeUnjR.v1sQaM22l6b4Xg.nWiS_WG5GliKd7ChrxH BvBMen2Ycn3mDI4g6_pvJg0ES4jFDxlvf0LnVeKBLB7Si3UPI1dsA3fnG_eJdAWwtp2xpjgHieu6 DzonPG6js62LKd11XQ9K_Vonx7kM3f9D8yTB3NzeeG1osuArrDc.FPpXrPQjWu4bD0nBDSriRiUD L02FBXsArNpAthGswV45whvqzlzf6puDrrPDTnZ0OtimLbLbKggG7dUu02K2iuTDope0r2YQiOTX IKS32z9CKV1ShI3m.n2TnViSlnSt.ev5trThFlsS9wfa5R9ye0TLZcwYDc6X.vImWbozGFGxPUBI HozLij9rR1v1d44M9zjJ8j2uiiY9S9jdzLUePFSm3pQ.1e3vSmm8_hXqHO_G34G5vQKAaTNFRUtC 09q7pv_fUu6QMJJBVH8.dyoKuSACg_Ryy.RspCTdYELyJ5hobPg1gfWntvAp.b6P00TIuLhuBRBd le2snXTA1tuVemSS_7Vd91UnzwOUU4gikilFOuPmaVjg4u3qUFtltMKfWENka0ynvpcM1XAwezeC In.1iyx0MqFALt.h3xTrq5qkrN8kCyaZJKmMYfYWi72YhG9lYPdB5m_4HAd3x3mARlkA4Nvo0IT3 2mw7FYDZ7Idd6wWJmBa9ixVGd8.gUIGbPgq0bO_OaFopCrX8JUTE7IP4fNUeRjS28__P7ipxW9WI 5Al07fX7kue2HJr9i3oF6WyVfYhQTLIk6xqnNQUn0R0vjn0y2aAbcK3nyOC7d.j3Fx_RbNwZzRtg hHqNDw21IUPFKb_EIBawr2kr_V08SkA-- Received: from sonic.gate.mail.ne1.yahoo.com by sonic312.consmr.mail.ne1.yahoo.com with HTTP; Wed, 26 Aug 2020 15:20:15 +0000 Received: by smtp420.mail.bf1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID 12a1ede8fa09b544263df0bf06dc9521; Wed, 26 Aug 2020 15:20: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, netdev@vger.kernel.org Subject: [PATCH v20 17/23] LSM: security_secid_to_secctx in netlink netfilter Date: Wed, 26 Aug 2020 07:52:41 -0700 Message-Id: <20200826145247.10029-18-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200826145247.10029-1-casey@schaufler-ca.com> References: <20200826145247.10029-1-casey@schaufler-ca.com> MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Change netlink netfilter interfaces to use lsmcontext pointers, and remove scaffolding. Reviewed-by: Kees Cook Reviewed-by: John Johansen Acked-by: Stephen Smalley Signed-off-by: Casey Schaufler cc: netdev@vger.kernel.org --- net/netfilter/nfnetlink_queue.c | 31 ++++++++++++------------------- 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c index d3f8e808c5d3..c830401f7792 100644 --- a/net/netfilter/nfnetlink_queue.c +++ b/net/netfilter/nfnetlink_queue.c @@ -301,12 +301,10 @@ 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 u32 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; @@ -318,14 +316,14 @@ 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; + return context->len; +#else + return 0; #endif - return seclen; } static u32 nfqnl_get_bridge_size(struct nf_queue_entry *entry) @@ -401,8 +399,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; + struct lsmcontext context = { }; u32 seclen = 0; size = nlmsg_total_size(sizeof(struct nfgenmsg)) @@ -469,7 +466,7 @@ 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); + seclen = nfqnl_get_sk_secctx(entskb, &context); if (seclen) size += nla_total_size(seclen); } @@ -604,7 +601,7 @@ 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 (seclen && 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) @@ -632,10 +629,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 (seclen) + security_release_secctx(&context); return skb; nla_put_failure: @@ -643,10 +638,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 (seclen) + security_release_secctx(&context); return NULL; } From patchwork Wed Aug 26 14:52:42 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 1352020 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=schaufler-ca.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=yahoo.com header.i=@yahoo.com header.a=rsa-sha256 header.s=s2048 header.b=l+p/McRY; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 4Bc8hp4DXyz9sTR for ; Thu, 27 Aug 2020 01:21:30 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727941AbgHZPV2 (ORCPT ); Wed, 26 Aug 2020 11:21:28 -0400 Received: from sonic310-30.consmr.mail.ne1.yahoo.com ([66.163.186.211]:38358 "EHLO sonic310-30.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727914AbgHZPVY (ORCPT ); Wed, 26 Aug 2020 11:21:24 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1598455282; bh=kuTN96gAmDvur/hqp0u4rFs9cVxW+giZU4wYl0+pxOQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=l+p/McRYsx+0Fz27KWvBTDRC8ZrgeUkBWOwFbj7+Rj8138FhaBKK2kXVRf+JHyxPwgoISRc5lH/raUJhjFxy1ZDHTF7mvhNYyketoJ675qHxk0VTXGvRBXAQIEXEYcTZiT8he9zoU29DXsOp8LfRirMBuKdEyKi1i/uxgluzLoftddITXNd6mXCzu673zbV8NuC5lwMt8QKK7+Kf1jvoZwrWZX8Z+oxhZI+bwADpl9SlpPwiBMCpuI8GfmW61DHFoLOHSeHOL5sUj+mgPjU7PVhT09n+XSlDgDeAY/sqB45m1BZlhdZEHp6t/A1uCQxoqRN9PdRhMPT57cv0Tnba4w== X-YMail-OSG: dxNq7SMVM1n0L5TAy2luh3OB32h0zimr13emS3O1eKb9Fkna38nKPjfqDJo5750 qTB_5vatYyVOS.Eb7liIw0NGxVCTMnahtndukjsCpOb8zI30flQ5RzoLvnSOrpGAEwkz_iyHnZ5q saBljdMe5CxBP1wpyfakHeTFMNux8OIQWKZPrX3wEmxs2nOT2_y03SFmt2xV_jojVTYVdXORgK9H g6zgxTlBIG9IL.Pj8_uuuTRbpppU.zAtEOQ5InZ.seB7O731aOYLkzW9buEHSwFntDCSEntmuL.a tFJzoL.WojXkgAdcuixFXfeskBWvm6UJRDzOaX_e9XWy7YulI.QZtCFy34bby8Ogh7im6FU5g86u FD5c9kr57Jh4MGxxxn2bclkjUshx5OpEziGo3_R8W8dUpDdSSDlBfXpAaztpn7WPt64IhrYCc0Yv vEFFN0XJV_Ppwjvfi35pZIJIMjXbxMYqfW5VETwnnobGpP1CfIForIaPJoBrYMllHOBOfsnkHaUZ SABrvwqeXb_aEQqk_gfo7iTZWOzuh6WsKNmalPJmISt0Wj2yA.nI7a.pFq4hBKbxfW1IFtULRRvz 1LPGVpP0JFO4SsWzndmQCidCc0fuCLPkMWizRfx1VEFh60O077Y0qtUtU_HGcS9nlsg7IvOJvR7r BVBBeDv4XtiqNxlT8PULMvm8SMfJymCqCDibWSOO1mjBRcDdiQaqc.ktezIDofntVljxRpi8D.j6 reTQ2U2waSJ0oaUy8VCY1Hr3nwOi_KdIMdfiRiZRCCmEnOdzn9CyczNTCIhiNK0kyBvunkbWIya4 RqsaT36HlnRjyh8hYmhN9jF30y4TCVCS0OO8Oac_eu3sYZPwT7TS8zJSK5AJ4nJszt8I8QqUOPtj cinNpAEg7tkZ33zqEM5Xpj06ovczNArbhe1VyQKOW4jcmiw0zuVFanwqu4BdiYR4gtpQNZsK_ki. QjD._12F9AF28O611z80Ca.rKneFESSHzwFxgplzop0ri96IVe5xNxQgG6y_FJLlFMKoZr5W3.Rg JFjc.f76enshJRncz7SG0RsekKCD7xjWQOzgvEibLP217M9BUxbLmn_3q_tltJ16H5d11Q5X7TyN 9VlkIhDnue.MM8X48MV3qvpmX2G8.snetnSyyG3Pm5F.m262Vh7DtJCjmHOQruT4z_xi6PS.WpT. qXl0xH7SeNKj82RFN4xsmwno1i8E_oBCMheGye5i5xYOdwRjxfzwo9Pp37uqXFo4eiGO3bnSgeZC RLsBJMWceV7jLqyzCLdsBHxp6osAHIww8AJprJo.F5fr0GStV.FtDYx4miBBy420nusVebh8tJ6A .TBHXoXdkdxn2diFqc5bX8lNSztZlmjHac9PZO0NHt1vgKRfkNDUVFE7qB_3DJLU8Q.mssYyenPf QzYsiBhLhpP.ea4KMMZJnq95Zy1Xt3NVTanVquWSvJOy_2cX6wylu25vSSHDR9DOrHwZizugH9li g1R9QPXd578dnYryDhBeM.i3FrWJs5SM0U2fKSKQ4yWwx5_OPqanDMRLo4mgq2Fx1nW11XQk7Eci 8u4zCn33jNCtUODyMZb54FjZT.aBMjyUSrp5oBzNGWUUYRBvaHfY- Received: from sonic.gate.mail.ne1.yahoo.com by sonic310.consmr.mail.ne1.yahoo.com with HTTP; Wed, 26 Aug 2020 15:21:22 +0000 Received: by smtp418.mail.ne1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID 6c18058b589109d683b0b083d2897140; Wed, 26 Aug 2020 15:21:18 +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, netdev@vger.kernel.org Subject: [PATCH v20 18/23] NET: Store LSM netlabel data in a lsmblob Date: Wed, 26 Aug 2020 07:52:42 -0700 Message-Id: <20200826145247.10029-19-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200826145247.10029-1-casey@schaufler-ca.com> References: <20200826145247.10029-1-casey@schaufler-ca.com> MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.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 Signed-off-by: Casey Schaufler Cc: netdev@vger.kernel.org Acked-by: Paul Moore --- include/net/netlabel.h | 8 +-- net/ipv4/cipso_ipv4.c | 27 ++++++---- 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_lsm.c | 5 +- security/smack/smackfs.c | 10 ++-- 12 files changed, 65 insertions(+), 82 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 2eb71579f4d2..8182b923e802 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 @@ -1469,7 +1471,12 @@ 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. This should never become an issue. + * The check is made from an abundance of caution. */ + 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; } @@ -1489,7 +1496,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 5e1239cef000..bbfaff539416 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 cf4c56beb3ec..c14a485ff045 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, @@ -497,13 +491,8 @@ static int netlbl_unlhsh_remove_addr4(struct net *net, addr->s_addr, mask->s_addr); if (dev != NULL) 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); @@ -544,7 +533,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); @@ -563,13 +551,8 @@ static int netlbl_unlhsh_remove_addr6(struct net *net, addr, mask); if (dev != NULL) 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); @@ -923,14 +906,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); } /** @@ -977,11 +954,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); } /** @@ -1093,8 +1067,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, @@ -1132,7 +1105,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, @@ -1146,14 +1119,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, @@ -1505,7 +1474,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) @@ -1518,7 +1487,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 f73dec68ee32..89c22769506b 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -6945,7 +6945,7 @@ static int selinux_perf_event_write(struct perf_event *event) } #endif -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 b0e02cfe3ce1..cee2987647dd 100644 --- a/security/selinux/include/security.h +++ b/security/selinux/include/security.h @@ -71,6 +71,7 @@ struct netlbl_lsm_secattr; extern int selinux_enabled_boot; +extern struct lsm_id selinux_lsmid; /* Policy capabilities */ enum { diff --git a/security/selinux/netlabel.c b/security/selinux/netlabel.c index 6a94b31b5472..d8d7603ab14e 100644 --- a/security/selinux/netlabel.c +++ b/security/selinux/netlabel.c @@ -108,7 +108,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 1caf4e603309..ffad57e41168 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c @@ -3637,7 +3637,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); @@ -3710,7 +3710,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 7481fa71de19..c284b104e1cc 100644 --- a/security/smack/smack.h +++ b/security/smack/smack.h @@ -310,6 +310,7 @@ void smk_destroy_label_list(struct list_head *list); * Shared data. */ extern int smack_enabled; +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_lsm.c b/security/smack/smack_lsm.c index 8b708cca921a..6f0cdb40addc 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -3751,7 +3751,8 @@ static struct smack_known *smack_from_secattr(struct netlbl_lsm_secattr *sap, /* * 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]); /* * Without guidance regarding the smack value * for the packet fall back on the network @@ -4656,7 +4657,7 @@ struct lsm_blob_sizes smack_blob_sizes __lsm_ro_after_init = { .lbs_sock = sizeof(struct socket_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 9c4308077574..dcabf6bd8faa 100644 --- a/security/smack/smackfs.c +++ b/security/smack/smackfs.c @@ -1136,6 +1136,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; @@ -1267,10 +1268,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;