From: Trond Myklebust <trondmy@gmail.com>
To: Anna Schumaker <Anna.Schumaker@netapp.com>
Cc: linux-nfs@vger.kernel.org
Subject: [PATCH 7/9] NFS: Convert NFSv2 to use the container user namespace
Date: Wed, 24 Apr 2019 17:46:48 -0400 [thread overview]
Message-ID: <20190424214650.4658-8-trond.myklebust@hammerspace.com> (raw)
In-Reply-To: <20190424214650.4658-7-trond.myklebust@hammerspace.com>
When mapping NFS identities, we want to substitute for the uids and
gids on the wire as we would for the AUTH_UNIX creds.
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
---
fs/nfs/nfs2xdr.c | 58 ++++++++++++++++++++++++++++++++----------------
1 file changed, 39 insertions(+), 19 deletions(-)
diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c
index a7ed29de0a40..572794dab4b1 100644
--- a/fs/nfs/nfs2xdr.c
+++ b/fs/nfs/nfs2xdr.c
@@ -76,6 +76,20 @@ static int nfs_stat_to_errno(enum nfs_stat);
* or decoded inline.
*/
+static struct user_namespace *rpc_userns(const struct rpc_clnt *clnt)
+{
+ if (clnt && clnt->cl_cred)
+ return clnt->cl_cred->user_ns;
+ return &init_user_ns;
+}
+
+static struct user_namespace *rpc_rqst_userns(const struct rpc_rqst *rqstp)
+{
+ if (rqstp->rq_task)
+ return rpc_userns(rqstp->rq_task->tk_client);
+ return &init_user_ns;
+}
+
/*
* typedef opaque nfsdata<>;
*/
@@ -248,7 +262,8 @@ static __be32 *xdr_decode_time(__be32 *p, struct timespec *timep)
* };
*
*/
-static int decode_fattr(struct xdr_stream *xdr, struct nfs_fattr *fattr)
+static int decode_fattr(struct xdr_stream *xdr, struct nfs_fattr *fattr,
+ struct user_namespace *userns)
{
u32 rdev, type;
__be32 *p;
@@ -263,10 +278,10 @@ static int decode_fattr(struct xdr_stream *xdr, struct nfs_fattr *fattr)
fattr->mode = be32_to_cpup(p++);
fattr->nlink = be32_to_cpup(p++);
- fattr->uid = make_kuid(&init_user_ns, be32_to_cpup(p++));
+ fattr->uid = make_kuid(userns, be32_to_cpup(p++));
if (!uid_valid(fattr->uid))
goto out_uid;
- fattr->gid = make_kgid(&init_user_ns, be32_to_cpup(p++));
+ fattr->gid = make_kgid(userns, be32_to_cpup(p++));
if (!gid_valid(fattr->gid))
goto out_gid;
@@ -321,7 +336,8 @@ static __be32 *xdr_time_not_set(__be32 *p)
return p;
}
-static void encode_sattr(struct xdr_stream *xdr, const struct iattr *attr)
+static void encode_sattr(struct xdr_stream *xdr, const struct iattr *attr,
+ struct user_namespace *userns)
{
struct timespec ts;
__be32 *p;
@@ -333,11 +349,11 @@ static void encode_sattr(struct xdr_stream *xdr, const struct iattr *attr)
else
*p++ = cpu_to_be32(NFS2_SATTR_NOT_SET);
if (attr->ia_valid & ATTR_UID)
- *p++ = cpu_to_be32(from_kuid(&init_user_ns, attr->ia_uid));
+ *p++ = cpu_to_be32(from_kuid_munged(userns, attr->ia_uid));
else
*p++ = cpu_to_be32(NFS2_SATTR_NOT_SET);
if (attr->ia_valid & ATTR_GID)
- *p++ = cpu_to_be32(from_kgid(&init_user_ns, attr->ia_gid));
+ *p++ = cpu_to_be32(from_kgid_munged(userns, attr->ia_gid));
else
*p++ = cpu_to_be32(NFS2_SATTR_NOT_SET);
if (attr->ia_valid & ATTR_SIZE)
@@ -451,7 +467,8 @@ static int decode_path(struct xdr_stream *xdr)
* };
*/
static int decode_attrstat(struct xdr_stream *xdr, struct nfs_fattr *result,
- __u32 *op_status)
+ __u32 *op_status,
+ struct user_namespace *userns)
{
enum nfs_stat status;
int error;
@@ -463,7 +480,7 @@ static int decode_attrstat(struct xdr_stream *xdr, struct nfs_fattr *result,
*op_status = status;
if (status != NFS_OK)
goto out_default;
- error = decode_fattr(xdr, result);
+ error = decode_fattr(xdr, result, userns);
out:
return error;
out_default:
@@ -498,19 +515,21 @@ static void encode_diropargs(struct xdr_stream *xdr, const struct nfs_fh *fh,
* void;
* };
*/
-static int decode_diropok(struct xdr_stream *xdr, struct nfs_diropok *result)
+static int decode_diropok(struct xdr_stream *xdr, struct nfs_diropok *result,
+ struct user_namespace *userns)
{
int error;
error = decode_fhandle(xdr, result->fh);
if (unlikely(error))
goto out;
- error = decode_fattr(xdr, result->fattr);
+ error = decode_fattr(xdr, result->fattr, userns);
out:
return error;
}
-static int decode_diropres(struct xdr_stream *xdr, struct nfs_diropok *result)
+static int decode_diropres(struct xdr_stream *xdr, struct nfs_diropok *result,
+ struct user_namespace *userns)
{
enum nfs_stat status;
int error;
@@ -520,7 +539,7 @@ static int decode_diropres(struct xdr_stream *xdr, struct nfs_diropok *result)
goto out;
if (status != NFS_OK)
goto out_default;
- error = decode_diropok(xdr, result);
+ error = decode_diropok(xdr, result, userns);
out:
return error;
out_default:
@@ -559,7 +578,7 @@ static void nfs2_xdr_enc_sattrargs(struct rpc_rqst *req,
const struct nfs_sattrargs *args = data;
encode_fhandle(xdr, args->fh);
- encode_sattr(xdr, args->sattr);
+ encode_sattr(xdr, args->sattr, rpc_rqst_userns(req));
}
static void nfs2_xdr_enc_diropargs(struct rpc_rqst *req,
@@ -674,7 +693,7 @@ static void nfs2_xdr_enc_createargs(struct rpc_rqst *req,
const struct nfs_createargs *args = data;
encode_diropargs(xdr, args->fh, args->name, args->len);
- encode_sattr(xdr, args->sattr);
+ encode_sattr(xdr, args->sattr, rpc_rqst_userns(req));
}
static void nfs2_xdr_enc_removeargs(struct rpc_rqst *req,
@@ -741,7 +760,7 @@ static void nfs2_xdr_enc_symlinkargs(struct rpc_rqst *req,
encode_diropargs(xdr, args->fromfh, args->fromname, args->fromlen);
encode_path(xdr, args->pages, args->pathlen);
- encode_sattr(xdr, args->sattr);
+ encode_sattr(xdr, args->sattr, rpc_rqst_userns(req));
}
/*
@@ -803,13 +822,13 @@ static int nfs2_xdr_dec_stat(struct rpc_rqst *req, struct xdr_stream *xdr,
static int nfs2_xdr_dec_attrstat(struct rpc_rqst *req, struct xdr_stream *xdr,
void *result)
{
- return decode_attrstat(xdr, result, NULL);
+ return decode_attrstat(xdr, result, NULL, rpc_rqst_userns(req));
}
static int nfs2_xdr_dec_diropres(struct rpc_rqst *req, struct xdr_stream *xdr,
void *result)
{
- return decode_diropres(xdr, result);
+ return decode_diropres(xdr, result, rpc_rqst_userns(req));
}
/*
@@ -864,7 +883,7 @@ static int nfs2_xdr_dec_readres(struct rpc_rqst *req, struct xdr_stream *xdr,
result->op_status = status;
if (status != NFS_OK)
goto out_default;
- error = decode_fattr(xdr, result->fattr);
+ error = decode_fattr(xdr, result->fattr, rpc_rqst_userns(req));
if (unlikely(error))
goto out;
error = decode_nfsdata(xdr, result);
@@ -881,7 +900,8 @@ static int nfs2_xdr_dec_writeres(struct rpc_rqst *req, struct xdr_stream *xdr,
/* All NFSv2 writes are "file sync" writes */
result->verf->committed = NFS_FILE_SYNC;
- return decode_attrstat(xdr, result->fattr, &result->op_status);
+ return decode_attrstat(xdr, result->fattr, &result->op_status,
+ rpc_rqst_userns(req));
}
/**
--
2.21.0
next prev parent reply other threads:[~2019-04-24 21:49 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-04-24 21:46 [PATCH 0/9] Client container fixes Trond Myklebust
2019-04-24 21:46 ` [PATCH 1/9] SUNRPC: Cache cred of process creating the rpc_client Trond Myklebust
2019-04-24 21:46 ` [PATCH 2/9] NFS: Store the credential of the mount process in the nfs_server Trond Myklebust
2019-04-24 21:46 ` [PATCH 3/9] SUNRPC: Use the client user namespace when encoding creds Trond Myklebust
2019-04-24 21:46 ` [PATCH 4/9] SUNRPC: Use namespace of listening daemon in the client AUTH_GSS upcall Trond Myklebust
2019-04-24 21:46 ` [PATCH 5/9] NFS: Convert NFSv3 to use the container user namespace Trond Myklebust
2019-04-24 21:46 ` [PATCH 6/9] NFSv4: Convert the NFS client idmapper " Trond Myklebust
2019-04-24 21:46 ` Trond Myklebust [this message]
2019-04-24 21:46 ` [PATCH 8/9] NFS: When mounting, don't share filesystems between different user namespaces Trond Myklebust
2019-04-24 21:46 ` [PATCH 9/9] lockd: Store the lockd client credential in struct nlm_host Trond Myklebust
2019-04-25 14:32 ` [PATCH 6/9] NFSv4: Convert the NFS client idmapper to use the container user namespace J. Bruce Fields
2019-04-25 15:00 ` Trond Myklebust
2019-04-25 15:33 ` bfields
2019-04-25 16:40 ` Trond Myklebust
2019-04-25 16:45 ` bfields
2019-04-25 16:48 ` Trond Myklebust
2019-04-25 20:16 ` bfields
2019-06-14 18:52 ` [PATCH 1/9] SUNRPC: Cache cred of process creating the rpc_client Ido Schimmel
2019-06-20 12:33 ` Ido Schimmel
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=20190424214650.4658-8-trond.myklebust@hammerspace.com \
--to=trondmy@gmail.com \
--cc=Anna.Schumaker@netapp.com \
--cc=linux-nfs@vger.kernel.org \
/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).