Linux-NFS Archive on lore.kernel.org
 help / color / Atom feed
From: Trond Myklebust <trondmy@hammerspace.com>
To: "bfields@fieldses.org" <bfields@fieldses.org>
Cc: "linux-nfs@vger.kernel.org" <linux-nfs@vger.kernel.org>,
	"Anna.Schumaker@netapp.com" <Anna.Schumaker@netapp.com>
Subject: Re: [PATCH 6/9] NFSv4: Convert the NFS client idmapper to use the container user namespace
Date: Thu, 25 Apr 2019 15:00:22 +0000
Message-ID: <e94c2488d89ae13675f9931d013a3d711459ecad.camel@hammerspace.com> (raw)
In-Reply-To: <20190425143243.GA8133@fieldses.org>

On Thu, 2019-04-25 at 10:32 -0400, J. Bruce Fields wrote:
> On Wed, Apr 24, 2019 at 05:46:47PM -0400, Trond Myklebust wrote:
> > When mapping NFS identities using the NFSv4 idmapper, we want to
> > substitute
> > for the uids and gids that would normally go on the wire as part of
> > a
> > NFSv3 request. So we use the same mapping in the NFSv4 upcall as we
> > use in the NFSv3 RPC call (i.e. the mapping stored in the rpc_clnt
> > cred).
> 
> I'm a little lost.  Do I have it right that the following id's are
> all
> the same?:
> 
> 	- id's used on the wire
> 	- id's used in NFSv4 idmapper upcalls
> 	- id's used in the namespace of the mounting process
> 
> And is it assumed that those are all in one namespace?  So different
> containers can't use different on-the-wire id's?

The assumption is that if you have enough privileges to mount a
filesystem using the NFS client, then you would also have enough
privileges to run a userspace client, so there is little point in
restricting the NFS client.

So the guiding principle is that a NFS client mount that is started in
a container should behave as if it were started by a process in a "real
VM". That means that the root uid/gid in the container maps to a root
uid/gid on the wire.
Ditto, if there is a need to run the idmapper in the container, then
the expectation is that processes running as 'user' with uid 'u', will
see their creds mapped correctly by the idmapper. Again, that's what
you would see if the process were running in a VM instead of a
container.

Does that all make sense?

So this means that any orchestrator software which may be setting up
NFS mounts as part of setting up the container has 2 options:

   1. Either perform the mount outside the container namespaces, in which
      case the container process uids/gids are mapped from their
      user_namespace into the user_namespace of the orchestrator, and the
      uids/gids on the wire will reflect those mapped uids/gids (so uid 0
      in the container will be mapped to uid xxx where xxx is decided by
      the orchestrator).
   2. Perform the mount inside the container namespaces, in which case the
      container process uids/gids go on the wire as-is.

Cheers
  Trond

> 
> --b.
> 
> > Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
> > ---
> >  fs/nfs/nfs4idmap.c | 27 ++++++++++++++++++++-------
> >  1 file changed, 20 insertions(+), 7 deletions(-)
> > 
> > diff --git a/fs/nfs/nfs4idmap.c b/fs/nfs/nfs4idmap.c
> > index bf34ddaa2ad7..4884fdae28fb 100644
> > --- a/fs/nfs/nfs4idmap.c
> > +++ b/fs/nfs/nfs4idmap.c
> > @@ -69,8 +69,16 @@ struct idmap {
> >  	struct rpc_pipe		*idmap_pipe;
> >  	struct idmap_legacy_upcalldata *idmap_upcall_data;
> >  	struct mutex		idmap_mutex;
> > +	const struct cred	*cred;
> >  };
> >  
> > +static struct user_namespace *idmap_userns(const struct idmap
> > *idmap)
> > +{
> > +	if (idmap && idmap->cred)
> > +		return idmap->cred->user_ns;
> > +	return &init_user_ns;
> > +}
> > +
> >  /**
> >   * nfs_fattr_init_names - initialise the nfs_fattr
> > owner_name/group_name fields
> >   * @fattr: fully initialised struct nfs_fattr
> > @@ -271,14 +279,15 @@ static struct key
> > *nfs_idmap_request_key(const char *name, size_t namelen,
> >  					 const char *type, struct idmap
> > *idmap)
> >  {
> >  	char *desc;
> > -	struct key *rkey;
> > +	struct key *rkey = ERR_PTR(-EAGAIN);
> >  	ssize_t ret;
> >  
> >  	ret = nfs_idmap_get_desc(name, namelen, type, strlen(type),
> > &desc);
> >  	if (ret < 0)
> >  		return ERR_PTR(ret);
> >  
> > -	rkey = request_key(&key_type_id_resolver, desc, "");
> > +	if (!idmap->cred || idmap->cred->user_ns == &init_user_ns)
> > +		rkey = request_key(&key_type_id_resolver, desc, "");
> >  	if (IS_ERR(rkey)) {
> >  		mutex_lock(&idmap->idmap_mutex);
> >  		rkey =
> > request_key_with_auxdata(&key_type_id_resolver_legacy,
> > @@ -452,6 +461,9 @@ nfs_idmap_new(struct nfs_client *clp)
> >  	if (idmap == NULL)
> >  		return -ENOMEM;
> >  
> > +	mutex_init(&idmap->idmap_mutex);
> > +	idmap->cred = get_cred(clp->cl_rpcclient->cl_cred);
> > +
> >  	rpc_init_pipe_dir_object(&idmap->idmap_pdo,
> >  			&nfs_idmap_pipe_dir_object_ops,
> >  			idmap);
> > @@ -462,7 +474,6 @@ nfs_idmap_new(struct nfs_client *clp)
> >  		goto err;
> >  	}
> >  	idmap->idmap_pipe = pipe;
> > -	mutex_init(&idmap->idmap_mutex);
> >  
> >  	error = rpc_add_pipe_dir_object(clp->cl_net,
> >  			&clp->cl_rpcclient->cl_pipedir_objects,
> > @@ -475,6 +486,7 @@ nfs_idmap_new(struct nfs_client *clp)
> >  err_destroy_pipe:
> >  	rpc_destroy_pipe_data(idmap->idmap_pipe);
> >  err:
> > +	put_cred(idmap->cred);
> >  	kfree(idmap);
> >  	return error;
> >  }
> > @@ -491,6 +503,7 @@ nfs_idmap_delete(struct nfs_client *clp)
> >  			&clp->cl_rpcclient->cl_pipedir_objects,
> >  			&idmap->idmap_pdo);
> >  	rpc_destroy_pipe_data(idmap->idmap_pipe);
> > +	put_cred(idmap->cred);
> >  	kfree(idmap);
> >  }
> >  
> > @@ -735,7 +748,7 @@ int nfs_map_name_to_uid(const struct nfs_server
> > *server, const char *name, size_
> >  	if (!nfs_map_string_to_numeric(name, namelen, &id))
> >  		ret = nfs_idmap_lookup_id(name, namelen, "uid", &id,
> > idmap);
> >  	if (ret == 0) {
> > -		*uid = make_kuid(&init_user_ns, id);
> > +		*uid = make_kuid(idmap_userns(idmap), id);
> >  		if (!uid_valid(*uid))
> >  			ret = -ERANGE;
> >  	}
> > @@ -752,7 +765,7 @@ int nfs_map_group_to_gid(const struct
> > nfs_server *server, const char *name, size
> >  	if (!nfs_map_string_to_numeric(name, namelen, &id))
> >  		ret = nfs_idmap_lookup_id(name, namelen, "gid", &id,
> > idmap);
> >  	if (ret == 0) {
> > -		*gid = make_kgid(&init_user_ns, id);
> > +		*gid = make_kgid(idmap_userns(idmap), id);
> >  		if (!gid_valid(*gid))
> >  			ret = -ERANGE;
> >  	}
> > @@ -766,7 +779,7 @@ int nfs_map_uid_to_name(const struct nfs_server
> > *server, kuid_t uid, char *buf,
> >  	int ret = -EINVAL;
> >  	__u32 id;
> >  
> > -	id = from_kuid(&init_user_ns, uid);
> > +	id = from_kuid_munged(idmap_userns(idmap), uid);
> >  	if (!(server->caps & NFS_CAP_UIDGID_NOMAP))
> >  		ret = nfs_idmap_lookup_name(id, "user", buf, buflen,
> > idmap);
> >  	if (ret < 0)
> > @@ -780,7 +793,7 @@ int nfs_map_gid_to_group(const struct
> > nfs_server *server, kgid_t gid, char *buf,
> >  	int ret = -EINVAL;
> >  	__u32 id;
> >  
> > -	id = from_kgid(&init_user_ns, gid);
> > +	id = from_kgid_munged(idmap_userns(idmap), gid);
> >  	if (!(server->caps & NFS_CAP_UIDGID_NOMAP))
> >  		ret = nfs_idmap_lookup_name(id, "group", buf, buflen,
> > idmap);
> >  	if (ret < 0)
> > -- 
> > 2.21.0
-- 
Trond Myklebust
Linux NFS client maintainer, Hammerspace
trond.myklebust@hammerspace.com



  reply index

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             ` [PATCH 7/9] NFS: Convert NFSv2 " Trond Myklebust
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 bfields
2019-04-25 15:00               ` Trond Myklebust [this message]
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 publically 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=e94c2488d89ae13675f9931d013a3d711459ecad.camel@hammerspace.com \
    --to=trondmy@hammerspace.com \
    --cc=Anna.Schumaker@netapp.com \
    --cc=bfields@fieldses.org \
    --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

Linux-NFS Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-nfs/0 linux-nfs/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 linux-nfs linux-nfs/ https://lore.kernel.org/linux-nfs \
		linux-nfs@vger.kernel.org
	public-inbox-index linux-nfs

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-nfs


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git