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) |
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, | |||
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); |