Commit ccfe51a5 authored by Trond Myklebust's avatar Trond Myklebust Committed by J. Bruce Fields

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: default avatarTrond Myklebust <trond.myklebust@hammerspace.com>
Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
parent 40373b12
...@@ -500,7 +500,7 @@ static int unix_gid_parse(struct cache_detail *cd, ...@@ -500,7 +500,7 @@ static int unix_gid_parse(struct cache_detail *cd,
rv = get_int(&mesg, &id); rv = get_int(&mesg, &id);
if (rv) if (rv)
return -EINVAL; return -EINVAL;
uid = make_kuid(&init_user_ns, id); uid = make_kuid(current_user_ns(), id);
ug.uid = uid; ug.uid = uid;
expiry = get_expiry(&mesg); expiry = get_expiry(&mesg);
...@@ -522,7 +522,7 @@ static int unix_gid_parse(struct cache_detail *cd, ...@@ -522,7 +522,7 @@ static int unix_gid_parse(struct cache_detail *cd,
err = -EINVAL; err = -EINVAL;
if (rv) if (rv)
goto out; goto out;
kgid = make_kgid(&init_user_ns, gid); kgid = make_kgid(current_user_ns(), gid);
if (!gid_valid(kgid)) if (!gid_valid(kgid))
goto out; goto out;
ug.gi->gid[i] = kgid; ug.gi->gid[i] = kgid;
...@@ -555,7 +555,7 @@ static int unix_gid_show(struct seq_file *m, ...@@ -555,7 +555,7 @@ static int unix_gid_show(struct seq_file *m,
struct cache_detail *cd, struct cache_detail *cd,
struct cache_head *h) 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; struct unix_gid *ug;
int i; int i;
int glen; int glen;
...@@ -796,6 +796,7 @@ svcauth_unix_accept(struct svc_rqst *rqstp, __be32 *authp) ...@@ -796,6 +796,7 @@ svcauth_unix_accept(struct svc_rqst *rqstp, __be32 *authp)
struct kvec *argv = &rqstp->rq_arg.head[0]; struct kvec *argv = &rqstp->rq_arg.head[0];
struct kvec *resv = &rqstp->rq_res.head[0]; struct kvec *resv = &rqstp->rq_res.head[0];
struct svc_cred *cred = &rqstp->rq_cred; struct svc_cred *cred = &rqstp->rq_cred;
struct user_namespace *userns;
u32 slen, i; u32 slen, i;
int len = argv->iov_len; int len = argv->iov_len;
...@@ -816,8 +817,10 @@ svcauth_unix_accept(struct svc_rqst *rqstp, __be32 *authp) ...@@ -816,8 +817,10 @@ svcauth_unix_accept(struct svc_rqst *rqstp, __be32 *authp)
* (export-specific) anonymous id by nfsd_setuser. * (export-specific) anonymous id by nfsd_setuser.
* Supplementary gid's will be left alone. * Supplementary gid's will be left alone.
*/ */
cred->cr_uid = make_kuid(&init_user_ns, svc_getnl(argv)); /* uid */ userns = (rqstp->rq_xprt && rqstp->rq_xprt->xpt_cred) ?
cred->cr_gid = make_kgid(&init_user_ns, svc_getnl(argv)); /* gid */ 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 */ slen = svc_getnl(argv); /* gids length */
if (slen > UNX_NGROUPS || (len -= (slen + 2)*4) < 0) if (slen > UNX_NGROUPS || (len -= (slen + 2)*4) < 0)
goto badcred; goto badcred;
...@@ -825,7 +828,7 @@ svcauth_unix_accept(struct svc_rqst *rqstp, __be32 *authp) ...@@ -825,7 +828,7 @@ svcauth_unix_accept(struct svc_rqst *rqstp, __be32 *authp)
if (cred->cr_group_info == NULL) if (cred->cr_group_info == NULL)
return SVC_CLOSE; return SVC_CLOSE;
for (i = 0; i < slen; i++) { 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; cred->cr_group_info->gid[i] = kgid;
} }
groups_sort(cred->cr_group_info); groups_sort(cred->cr_group_info);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment