From: "J. Bruce Fields" <bfields@fieldses.org>
To: andros@netapp.com
Cc: trond.myklebust@primarydata.com, schumaker.anna@gmail.com,
linux-nfs@vger.kernel.org
Subject: Re: [PATCH Version 5 08/17] SUNRPC AUTH_GSS RPCSEC_GSS_CREATE with label payload
Date: Fri, 10 Mar 2017 12:31:07 -0500 [thread overview]
Message-ID: <20170310173107.GE29791@fieldses.org> (raw)
In-Reply-To: <20170224221953.5502-9-andros@netapp.com>
On Fri, Feb 24, 2017 at 05:19:44PM -0500, andros@netapp.com wrote:
> From: Andy Adamson <andros@netapp.com>
>
> Signed-off-by: Andy Adamson <andros@netapp.com>
> ---
> net/sunrpc/auth_gss/auth_gss.c | 140 ++++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 138 insertions(+), 2 deletions(-)
>
> diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
> index 6ffb16d..98971cf 100644
> --- a/net/sunrpc/auth_gss/auth_gss.c
> +++ b/net/sunrpc/auth_gss/auth_gss.c
> @@ -52,9 +52,12 @@
> #include <linux/sunrpc/gss_api.h>
> #include <linux/uaccess.h>
> #include <linux/hashtable.h>
> +#include <linux/security.h>
>
> #include "../netns.h"
>
> +static int gss3_create_label(struct rpc_cred *cred, int gss_vers);
> +
> static const struct rpc_authops authgss_ops;
>
> static const struct rpc_credops gss_credops;
> @@ -128,6 +131,20 @@ gss_put_ctx(struct gss_cl_ctx *ctx)
> gss_free_ctx(ctx);
> }
>
> +/* gss3_label_enabled:
> + * Called to determine if Full Mode Mandatory Access Control (MAC)
> + * over a GSS connection is desired.
> + *
> + * Note:
> + * Currently Full Mode MAC is assuemed if SeLinux is enabled and
> + * RPCSEC_GSS version 3 is in use.
Eventually I guess we may want support for GSSv3-enabled copy without
full MAC, so we'll want some way to configure this.
Also, do I understand right that currently it's gssd that decides
whether to enable GSSv3, by passing down the new version number? How
will the user choose whether to enable GSSv3 or not?
Should that be a mount option?
The mount option could then cause some "use_gss3" flag to be added in
rpc_pipefs, in an info file or whatever. I think that'd also provide
backwards compatibility (if you're not already handling that some other
way), since gssd could use the presence of that flag to decide whether
the kernel was new enough to support the new downcall.
--b.
> + */
> +static inline bool
> +gss3_label_assertion_is_enabled(u32 rpcsec_version)
> +{
> + return (rpcsec_version == RPC_GSS3_VERSION && selinux_is_enabled());
> +}
> +
> /* gss_cred_set_ctx:
> * called by gss_upcall_callback and gss_create_upcall in order
> * to set the gss context. The actual exchange of an old context
> @@ -145,6 +162,7 @@ gss_cred_set_ctx(struct rpc_cred *cred, struct gss_cl_ctx *ctx)
> set_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags);
> smp_mb__before_atomic();
> clear_bit(RPCAUTH_CRED_NEW, &cred->cr_flags);
> + gss3_create_label(cred, ctx->gc_v);
> }
>
> static const void *
> @@ -1602,6 +1620,75 @@ static int gss_cred_is_negative_entry(struct rpc_cred *cred)
> #define GSS3_createres_maxsz (1 /* cr_hlen */ + \
> XDR_QUADLEN(1024) /* cr_handle*/ + \
> GSS3_createargs_maxsz)
> +#define GSS3_labelargs_maxsz (1 /* la_lfs */ + \
> + 1 /* la_pi */ + \
> + 1 /* la_label.len */ + \
> + XDR_QUADLEN(1024) /* la_label.data */)
> +#define GSS3_labelres_maxsz GSS3_labelargs_maxsz
> +
> +static void
> +gss3_enc_label(struct rpc_rqst *req, struct xdr_stream *xdr,
> + const struct gss3_create_args *g3ca)
> +{
> + struct gss3_label *gl;
> + __be32 *p;
> +
> + gl = &g3ca->ca_assertions[0].u.au_label;
> +
> + dprintk("RPC: %5u encoding GSSv3 label %s:%d\n", req->rq_task->tk_pid,
> + (char *)gl->la_label.data, gl->la_label.len);
> +
> + p = xdr_reserve_space(xdr, GSS3_labelargs_maxsz << 2);
> + *p++ = cpu_to_be32(0); /* la_lfs */
> + *p++ = cpu_to_be32(0); /* la_pi */
> + p = xdr_encode_netobj(p, &gl->la_label);
> +}
> +
> +static int
> +gss3_dec_label(struct rpc_rqst *req, struct xdr_stream *xdr,
> + struct gss3_create_res *g3cr)
> +{
> + struct gss3_label *gl;
> + struct gss3_assertion_u *g3a;
> + __be32 *p;
> +
> + /* Used to store assertion in parent gss_cl_ctx */
> + g3a = kzalloc(sizeof(*g3a), GFP_KERNEL);
> + if (!g3a)
> + goto out_err;
> +
> + g3a->au_type = GSS3_LABEL;
> + gl = &g3a->u.au_label;
> +
> + p = xdr_inline_decode(xdr, 12);
> + if (unlikely(!p))
> + goto out_overflow;
> +
> + gl->la_lfs = be32_to_cpup(p++);
> + gl->la_pi = be32_to_cpup(p++);
> + gl->la_label.len = be32_to_cpup(p++);
> +
> + p = xdr_inline_decode(xdr, gl->la_label.len);
> + if (unlikely(!p))
> + goto out_overflow;
> +
> + gl->la_label.data = kmemdup(p, gl->la_label.len, GFP_KERNEL);
> + if (!gl->la_label.data)
> + goto out_free_assert;
> +
> + g3cr->cr_assertions = g3a;
> +
> + return 0;
> +
> +out_free_assert:
> + kfree(g3a);
> +out_err:
> + return -EIO;
> +out_overflow:
> + pr_warn("RPC %s End of receive buffer. Remaining len: %tu words.\n",
> + __func__, xdr->end - xdr->p);
> + goto out_free_assert;
> +}
>
> static void
> gss3_enc_create(struct rpc_rqst *req, struct xdr_stream *xdr,
> @@ -1618,6 +1705,8 @@ gss3_enc_create(struct rpc_rqst *req, struct xdr_stream *xdr,
> *p++ = type;
> switch (type) {
> case GSS3_LABEL:
> + gss3_enc_label(req, xdr, g3ca);
> + break;
> case GSS3_PRIVS:
> default:
> /* drop through to return */
> @@ -1673,6 +1762,9 @@ gss3_dec_create(struct rpc_rqst *req, struct xdr_stream *xdr,
> type = be32_to_cpup(p++);
> switch (type) {
> case GSS3_LABEL:
> + if (gss3_dec_label(req, xdr, g3cr) != 0)
> + goto out_free_handle;
> + break;
> case GSS3_PRIVS:
> default:
> pr_warn("RPC Unsupported gss3 create assertion %d\n", type);
> @@ -1692,13 +1784,16 @@ gss3_dec_create(struct rpc_rqst *req, struct xdr_stream *xdr,
>
> #define RPC_PROC_NULL 0
>
> +#define GSS3_create_args_max (GSS3_createargs_maxsz + GSS3_labelargs_maxsz)
> +#define GSS3_create_res_max (GSS3_createres_maxsz + GSS3_labelres_maxsz)
> +
> struct rpc_procinfo gss3_label_assertion[] = {
> [RPC_GSS_PROC_CREATE] = {
> .p_proc = RPC_PROC_NULL,
> .p_encode = (kxdreproc_t)gss3_enc_create,
> .p_decode = (kxdrdproc_t)gss3_dec_create,
> - .p_arglen = GSS3_createargs_maxsz,
> - .p_replen = GSS3_createres_maxsz,
> + .p_arglen = GSS3_create_args_max,
> + .p_replen = GSS3_create_res_max,
> .p_statidx = RPC_GSS_PROC_CREATE,
> .p_timer = 0,
> .p_name = "GSS_PROC_CREATE",
> @@ -1773,6 +1868,47 @@ gss3_proc_create(struct rpc_cred *cred, struct gss3_assertion_u *asserts,
> return ret;
> }
>
> +/**
> + * GSS3 Label Assertion
> + *
> + * Support one label assertion
> + *
> + * XXX Return not checked. Should we fail nfs requests if
> + * a label fails to be created? I think the server enforcing
> + * Full Mode MAC will reject an NFS request that does not use
> + * a GSS3 (child) context with the correct label.
> + */
> +static int
> +gss3_create_label(struct rpc_cred *cred, int gss_vers)
> +{
> + struct gss3_assertion_u *asserts;
> + struct gss3_label *gl;
> + int ret;
> +
> + if (!gss3_label_assertion_is_enabled(gss_vers))
> + return -EINVAL;
> +
> + asserts = kzalloc(sizeof(*asserts), GFP_NOFS);
> + if (!asserts)
> + return -ENOMEM;
> +
> + /* NOTE: not setting la_lfs, la_pi. Do we even need them? */
> + asserts->au_type = GSS3_LABEL;
> + gl = &asserts->u.au_label;
> +
> + ret = -EINVAL;
> + ret = security_current_sid_to_context((char **)&gl->la_label.data,
> + &gl->la_label.len);
> + if (ret)
> + goto out_free_asserts;
> +
> + return gss3_proc_create(cred, asserts, 1);
> +
> +out_free_asserts:
> + kfree(asserts);
> + return ret;
> +}
> +
> /*
> * Refresh credentials. XXX - finish
> */
> --
> 2.9.3
next prev parent reply other threads:[~2017-03-10 17:31 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-02-24 22:19 [PATCH Version 5 00/17] RPCSEC_GSS3 full mode label kernel patch set andros
2017-02-24 22:19 ` [PATCH Version 5 01/17] SUNRPC handle unsupported RPCSEC_GSS security service andros
2017-03-09 21:54 ` J. Bruce Fields
2017-02-24 22:19 ` [PATCH Version 5 02/17] SUNRPC: RPCNULL call with payload for GSSv3 andros
2017-03-09 22:11 ` J. Bruce Fields
2017-02-24 22:19 ` [PATCH Version 5 03/17] SELINUX export security_current_sid_to_context andros
2017-02-24 22:19 ` [PATCH Version 5 04/17] SUNRPC GSSv3: base definitions andros
2017-02-24 22:19 ` [PATCH Version 5 05/17] SUNRPC AUTH_GSS get RPCSEC_GSS version from gssd downcall andros
2017-03-10 16:18 ` J. Bruce Fields
2017-02-24 22:19 ` [PATCH Version 5 06/17] SUNRPC AUTH_GSS gss3 reply verifier andros
2017-03-10 16:51 ` J. Bruce Fields
2017-02-24 22:19 ` [PATCH Version 5 07/17] SUNRPC AUTH_GSS RPCSEC_GSS_CREATE with no payload andros
2017-03-10 17:25 ` J. Bruce Fields
2017-02-24 22:19 ` [PATCH Version 5 08/17] SUNRPC AUTH_GSS RPCSEC_GSS_CREATE with label payload andros
2017-02-27 21:47 ` Anna Schumaker
2017-03-10 17:31 ` J. Bruce Fields [this message]
2017-03-10 17:33 ` J. Bruce Fields
2017-02-24 22:19 ` [PATCH Version 5 09/17] SUNRPC AUTH_GSS store GSS3 assertions in parent gss_cl_ctx andros
2017-02-24 22:19 ` [PATCH Version 5 10/17] SUNRPC AUTH_GSS store and use gss3 label assertion andros
2017-02-24 22:19 ` [PATCH Version 5 11/17] SUNRPC AUTH_GSS free assertions andros
2017-02-24 22:19 ` [PATCH Version 5 12/17] SUNRPC: AUTH_GSS add RPC_GSS_PROC_CREATE case for wrap and unwrap andros
2017-02-24 22:19 ` [PATCH Version 5 13/17] SUNRPC SVCAUTH_GSS allow RPCSEC_GSS version 1 or 3 andros
2017-02-24 22:19 ` [PATCH Version 5 14/17] SUNRPC SVCAUTH_GSS gss3 reply verifier andros
2017-02-24 22:19 ` [PATCH Version 5 15/17] SUNRPC SVCAUTH_GSS gss3 create label andros
2017-02-24 22:19 ` [PATCH Version 5 16/17] SUNRPC SVCAUTH_GSS set gss3 label on nfsd thread andros
2017-02-24 22:19 ` [PATCH Version 5 17/17] SUNRPC SVCAUTH_gss store gss3 child handles in parent rsc andros
2017-03-09 21:47 ` [PATCH Version 5 00/17] RPCSEC_GSS3 full mode label kernel patch set J. Bruce Fields
2017-03-10 14:48 ` Andy Adamson
2017-03-10 16:36 ` J. Bruce Fields
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20170310173107.GE29791@fieldses.org \
--to=bfields@fieldses.org \
--cc=andros@netapp.com \
--cc=linux-nfs@vger.kernel.org \
--cc=schumaker.anna@gmail.com \
--cc=trond.myklebust@primarydata.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).