diff options
author | Trond Myklebust <trondmy@gmail.com> | 2019-04-09 12:13:40 -0400 |
---|---|---|
committer | J. Bruce Fields <bfields@redhat.com> | 2019-04-24 09:46:35 -0400 |
commit | ccfe51a5161c17d24157c08f9963f351a89268fa (patch) | |
tree | 486bd214b8fc600eb3481af9ffe9ebe81643e8e9 | |
parent | 40373b125de6bab186e71d5ea5498bb2b845398b (diff) | |
download | lwn-ccfe51a5161c17d24157c08f9963f351a89268fa.tar.gz lwn-ccfe51a5161c17d24157c08f9963f351a89268fa.zip |
SUNRPC: Fix the server AUTH_UNIX userspace mappings
gid_parse() is part of a downcall, so uids and gids should be assumed
encoded using the current user namespace.
svcauth_unix_accept() is, on the other hand, decoding uids and gids from
the wire, so we assume those are encoded to match the user namespace of
the server process.
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
-rw-r--r-- | net/sunrpc/svcauth_unix.c | 15 |
1 files changed, 9 insertions, 6 deletions
diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c index fb9041b92f72..f92ef79c8ea5 100644 --- a/net/sunrpc/svcauth_unix.c +++ b/net/sunrpc/svcauth_unix.c @@ -500,7 +500,7 @@ static int unix_gid_parse(struct cache_detail *cd, rv = get_int(&mesg, &id); if (rv) return -EINVAL; - uid = make_kuid(&init_user_ns, id); + uid = make_kuid(current_user_ns(), id); ug.uid = uid; expiry = get_expiry(&mesg); @@ -522,7 +522,7 @@ static int unix_gid_parse(struct cache_detail *cd, err = -EINVAL; if (rv) goto out; - kgid = make_kgid(&init_user_ns, gid); + kgid = make_kgid(current_user_ns(), gid); if (!gid_valid(kgid)) goto out; ug.gi->gid[i] = kgid; @@ -555,7 +555,7 @@ static int unix_gid_show(struct seq_file *m, struct cache_detail *cd, struct cache_head *h) { - struct user_namespace *user_ns = &init_user_ns; + struct user_namespace *user_ns = m->file->f_cred->user_ns; struct unix_gid *ug; int i; int glen; @@ -796,6 +796,7 @@ svcauth_unix_accept(struct svc_rqst *rqstp, __be32 *authp) struct kvec *argv = &rqstp->rq_arg.head[0]; struct kvec *resv = &rqstp->rq_res.head[0]; struct svc_cred *cred = &rqstp->rq_cred; + struct user_namespace *userns; u32 slen, i; int len = argv->iov_len; @@ -816,8 +817,10 @@ svcauth_unix_accept(struct svc_rqst *rqstp, __be32 *authp) * (export-specific) anonymous id by nfsd_setuser. * Supplementary gid's will be left alone. */ - cred->cr_uid = make_kuid(&init_user_ns, svc_getnl(argv)); /* uid */ - cred->cr_gid = make_kgid(&init_user_ns, svc_getnl(argv)); /* gid */ + userns = (rqstp->rq_xprt && rqstp->rq_xprt->xpt_cred) ? + rqstp->rq_xprt->xpt_cred->user_ns : &init_user_ns; + cred->cr_uid = make_kuid(userns, svc_getnl(argv)); /* uid */ + cred->cr_gid = make_kgid(userns, svc_getnl(argv)); /* gid */ slen = svc_getnl(argv); /* gids length */ if (slen > UNX_NGROUPS || (len -= (slen + 2)*4) < 0) goto badcred; @@ -825,7 +828,7 @@ svcauth_unix_accept(struct svc_rqst *rqstp, __be32 *authp) if (cred->cr_group_info == NULL) return SVC_CLOSE; for (i = 0; i < slen; i++) { - kgid_t kgid = make_kgid(&init_user_ns, svc_getnl(argv)); + kgid_t kgid = make_kgid(userns, svc_getnl(argv)); cred->cr_group_info->gid[i] = kgid; } groups_sort(cred->cr_group_info); |