aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTrond Myklebust <trondmy@gmail.com>2019-04-09 12:13:40 -0400
committerJ. Bruce Fields <bfields@redhat.com>2019-04-24 09:46:35 -0400
commitccfe51a5161c17d24157c08f9963f351a89268fa (patch)
tree486bd214b8fc600eb3481af9ffe9ebe81643e8e9
parent40373b125de6bab186e71d5ea5498bb2b845398b (diff)
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.c15
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,
500 rv = get_int(&mesg, &id); 500 rv = get_int(&mesg, &id);
501 if (rv) 501 if (rv)
502 return -EINVAL; 502 return -EINVAL;
503 uid = make_kuid(&init_user_ns, id); 503 uid = make_kuid(current_user_ns(), id);
504 ug.uid = uid; 504 ug.uid = uid;
505 505
506 expiry = get_expiry(&mesg); 506 expiry = get_expiry(&mesg);
@@ -522,7 +522,7 @@ static int unix_gid_parse(struct cache_detail *cd,
522 err = -EINVAL; 522 err = -EINVAL;
523 if (rv) 523 if (rv)
524 goto out; 524 goto out;
525 kgid = make_kgid(&init_user_ns, gid); 525 kgid = make_kgid(current_user_ns(), gid);
526 if (!gid_valid(kgid)) 526 if (!gid_valid(kgid))
527 goto out; 527 goto out;
528 ug.gi->gid[i] = kgid; 528 ug.gi->gid[i] = kgid;
@@ -555,7 +555,7 @@ static int unix_gid_show(struct seq_file *m,
555 struct cache_detail *cd, 555 struct cache_detail *cd,
556 struct cache_head *h) 556 struct cache_head *h)
557{ 557{
558 struct user_namespace *user_ns = &init_user_ns; 558 struct user_namespace *user_ns = m->file->f_cred->user_ns;
559 struct unix_gid *ug; 559 struct unix_gid *ug;
560 int i; 560 int i;
561 int glen; 561 int glen;
@@ -796,6 +796,7 @@ svcauth_unix_accept(struct svc_rqst *rqstp, __be32 *authp)
796 struct kvec *argv = &rqstp->rq_arg.head[0]; 796 struct kvec *argv = &rqstp->rq_arg.head[0];
797 struct kvec *resv = &rqstp->rq_res.head[0]; 797 struct kvec *resv = &rqstp->rq_res.head[0];
798 struct svc_cred *cred = &rqstp->rq_cred; 798 struct svc_cred *cred = &rqstp->rq_cred;
799 struct user_namespace *userns;
799 u32 slen, i; 800 u32 slen, i;
800 int len = argv->iov_len; 801 int len = argv->iov_len;
801 802
@@ -816,8 +817,10 @@ svcauth_unix_accept(struct svc_rqst *rqstp, __be32 *authp)
816 * (export-specific) anonymous id by nfsd_setuser. 817 * (export-specific) anonymous id by nfsd_setuser.
817 * Supplementary gid's will be left alone. 818 * Supplementary gid's will be left alone.
818 */ 819 */
819 cred->cr_uid = make_kuid(&init_user_ns, svc_getnl(argv)); /* uid */ 820 userns = (rqstp->rq_xprt && rqstp->rq_xprt->xpt_cred) ?
820 cred->cr_gid = make_kgid(&init_user_ns, svc_getnl(argv)); /* gid */ 821 rqstp->rq_xprt->xpt_cred->user_ns : &init_user_ns;
822 cred->cr_uid = make_kuid(userns, svc_getnl(argv)); /* uid */
823 cred->cr_gid = make_kgid(userns, svc_getnl(argv)); /* gid */
821 slen = svc_getnl(argv); /* gids length */ 824 slen = svc_getnl(argv); /* gids length */
822 if (slen > UNX_NGROUPS || (len -= (slen + 2)*4) < 0) 825 if (slen > UNX_NGROUPS || (len -= (slen + 2)*4) < 0)
823 goto badcred; 826 goto badcred;
@@ -825,7 +828,7 @@ svcauth_unix_accept(struct svc_rqst *rqstp, __be32 *authp)
825 if (cred->cr_group_info == NULL) 828 if (cred->cr_group_info == NULL)
826 return SVC_CLOSE; 829 return SVC_CLOSE;
827 for (i = 0; i < slen; i++) { 830 for (i = 0; i < slen; i++) {
828 kgid_t kgid = make_kgid(&init_user_ns, svc_getnl(argv)); 831 kgid_t kgid = make_kgid(userns, svc_getnl(argv));
829 cred->cr_group_info->gid[i] = kgid; 832 cred->cr_group_info->gid[i] = kgid;
830 } 833 }
831 groups_sort(cred->cr_group_info); 834 groups_sort(cred->cr_group_info);