aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc/svcauth_unix.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sunrpc/svcauth_unix.c')
-rw-r--r--net/sunrpc/svcauth_unix.c43
1 files changed, 27 insertions, 16 deletions
diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c
index 4d0129203733..a1852e19ed0c 100644
--- a/net/sunrpc/svcauth_unix.c
+++ b/net/sunrpc/svcauth_unix.c
@@ -415,10 +415,15 @@ svcauth_unix_info_release(struct svc_xprt *xpt)
415 415
416struct unix_gid { 416struct unix_gid {
417 struct cache_head h; 417 struct cache_head h;
418 uid_t uid; 418 kuid_t uid;
419 struct group_info *gi; 419 struct group_info *gi;
420}; 420};
421 421
422static int unix_gid_hash(kuid_t uid)
423{
424 return hash_long(from_kuid(&init_user_ns, uid), GID_HASHBITS);
425}
426
422static void unix_gid_put(struct kref *kref) 427static void unix_gid_put(struct kref *kref)
423{ 428{
424 struct cache_head *item = container_of(kref, struct cache_head, ref); 429 struct cache_head *item = container_of(kref, struct cache_head, ref);
@@ -433,7 +438,7 @@ static int unix_gid_match(struct cache_head *corig, struct cache_head *cnew)
433{ 438{
434 struct unix_gid *orig = container_of(corig, struct unix_gid, h); 439 struct unix_gid *orig = container_of(corig, struct unix_gid, h);
435 struct unix_gid *new = container_of(cnew, struct unix_gid, h); 440 struct unix_gid *new = container_of(cnew, struct unix_gid, h);
436 return orig->uid == new->uid; 441 return uid_eq(orig->uid, new->uid);
437} 442}
438static void unix_gid_init(struct cache_head *cnew, struct cache_head *citem) 443static void unix_gid_init(struct cache_head *cnew, struct cache_head *citem)
439{ 444{
@@ -465,7 +470,7 @@ static void unix_gid_request(struct cache_detail *cd,
465 char tuid[20]; 470 char tuid[20];
466 struct unix_gid *ug = container_of(h, struct unix_gid, h); 471 struct unix_gid *ug = container_of(h, struct unix_gid, h);
467 472
468 snprintf(tuid, 20, "%u", ug->uid); 473 snprintf(tuid, 20, "%u", from_kuid(&init_user_ns, ug->uid));
469 qword_add(bpp, blen, tuid); 474 qword_add(bpp, blen, tuid);
470 (*bpp)[-1] = '\n'; 475 (*bpp)[-1] = '\n';
471} 476}
@@ -475,13 +480,14 @@ static int unix_gid_upcall(struct cache_detail *cd, struct cache_head *h)
475 return sunrpc_cache_pipe_upcall(cd, h, unix_gid_request); 480 return sunrpc_cache_pipe_upcall(cd, h, unix_gid_request);
476} 481}
477 482
478static struct unix_gid *unix_gid_lookup(struct cache_detail *cd, uid_t uid); 483static struct unix_gid *unix_gid_lookup(struct cache_detail *cd, kuid_t uid);
479 484
480static int unix_gid_parse(struct cache_detail *cd, 485static int unix_gid_parse(struct cache_detail *cd,
481 char *mesg, int mlen) 486 char *mesg, int mlen)
482{ 487{
483 /* uid expiry Ngid gid0 gid1 ... gidN-1 */ 488 /* uid expiry Ngid gid0 gid1 ... gidN-1 */
484 int uid; 489 int id;
490 kuid_t uid;
485 int gids; 491 int gids;
486 int rv; 492 int rv;
487 int i; 493 int i;
@@ -493,9 +499,12 @@ static int unix_gid_parse(struct cache_detail *cd,
493 return -EINVAL; 499 return -EINVAL;
494 mesg[mlen-1] = 0; 500 mesg[mlen-1] = 0;
495 501
496 rv = get_int(&mesg, &uid); 502 rv = get_int(&mesg, &id);
497 if (rv) 503 if (rv)
498 return -EINVAL; 504 return -EINVAL;
505 uid = make_kuid(&init_user_ns, id);
506 if (!uid_valid(uid))
507 return -EINVAL;
499 ug.uid = uid; 508 ug.uid = uid;
500 509
501 expiry = get_expiry(&mesg); 510 expiry = get_expiry(&mesg);
@@ -530,7 +539,7 @@ static int unix_gid_parse(struct cache_detail *cd,
530 ug.h.expiry_time = expiry; 539 ug.h.expiry_time = expiry;
531 ch = sunrpc_cache_update(cd, 540 ch = sunrpc_cache_update(cd,
532 &ug.h, &ugp->h, 541 &ug.h, &ugp->h,
533 hash_long(uid, GID_HASHBITS)); 542 unix_gid_hash(uid));
534 if (!ch) 543 if (!ch)
535 err = -ENOMEM; 544 err = -ENOMEM;
536 else { 545 else {
@@ -549,7 +558,7 @@ static int unix_gid_show(struct seq_file *m,
549 struct cache_detail *cd, 558 struct cache_detail *cd,
550 struct cache_head *h) 559 struct cache_head *h)
551{ 560{
552 struct user_namespace *user_ns = current_user_ns(); 561 struct user_namespace *user_ns = &init_user_ns;
553 struct unix_gid *ug; 562 struct unix_gid *ug;
554 int i; 563 int i;
555 int glen; 564 int glen;
@@ -565,7 +574,7 @@ static int unix_gid_show(struct seq_file *m,
565 else 574 else
566 glen = 0; 575 glen = 0;
567 576
568 seq_printf(m, "%u %d:", ug->uid, glen); 577 seq_printf(m, "%u %d:", from_kuid_munged(user_ns, ug->uid), glen);
569 for (i = 0; i < glen; i++) 578 for (i = 0; i < glen; i++)
570 seq_printf(m, " %d", from_kgid_munged(user_ns, GROUP_AT(ug->gi, i))); 579 seq_printf(m, " %d", from_kgid_munged(user_ns, GROUP_AT(ug->gi, i)));
571 seq_printf(m, "\n"); 580 seq_printf(m, "\n");
@@ -615,20 +624,20 @@ void unix_gid_cache_destroy(struct net *net)
615 cache_destroy_net(cd, net); 624 cache_destroy_net(cd, net);
616} 625}
617 626
618static struct unix_gid *unix_gid_lookup(struct cache_detail *cd, uid_t uid) 627static struct unix_gid *unix_gid_lookup(struct cache_detail *cd, kuid_t uid)
619{ 628{
620 struct unix_gid ug; 629 struct unix_gid ug;
621 struct cache_head *ch; 630 struct cache_head *ch;
622 631
623 ug.uid = uid; 632 ug.uid = uid;
624 ch = sunrpc_cache_lookup(cd, &ug.h, hash_long(uid, GID_HASHBITS)); 633 ch = sunrpc_cache_lookup(cd, &ug.h, unix_gid_hash(uid));
625 if (ch) 634 if (ch)
626 return container_of(ch, struct unix_gid, h); 635 return container_of(ch, struct unix_gid, h);
627 else 636 else
628 return NULL; 637 return NULL;
629} 638}
630 639
631static struct group_info *unix_gid_find(uid_t uid, struct svc_rqst *rqstp) 640static struct group_info *unix_gid_find(kuid_t uid, struct svc_rqst *rqstp)
632{ 641{
633 struct unix_gid *ug; 642 struct unix_gid *ug;
634 struct group_info *gi; 643 struct group_info *gi;
@@ -750,8 +759,8 @@ svcauth_null_accept(struct svc_rqst *rqstp, __be32 *authp)
750 } 759 }
751 760
752 /* Signal that mapping to nobody uid/gid is required */ 761 /* Signal that mapping to nobody uid/gid is required */
753 cred->cr_uid = (uid_t) -1; 762 cred->cr_uid = INVALID_UID;
754 cred->cr_gid = (gid_t) -1; 763 cred->cr_gid = INVALID_GID;
755 cred->cr_group_info = groups_alloc(0); 764 cred->cr_group_info = groups_alloc(0);
756 if (cred->cr_group_info == NULL) 765 if (cred->cr_group_info == NULL)
757 return SVC_CLOSE; /* kmalloc failure - client must retry */ 766 return SVC_CLOSE; /* kmalloc failure - client must retry */
@@ -812,8 +821,10 @@ svcauth_unix_accept(struct svc_rqst *rqstp, __be32 *authp)
812 argv->iov_base = (void*)((__be32*)argv->iov_base + slen); /* skip machname */ 821 argv->iov_base = (void*)((__be32*)argv->iov_base + slen); /* skip machname */
813 argv->iov_len -= slen*4; 822 argv->iov_len -= slen*4;
814 823
815 cred->cr_uid = svc_getnl(argv); /* uid */ 824 cred->cr_uid = make_kuid(&init_user_ns, svc_getnl(argv)); /* uid */
816 cred->cr_gid = svc_getnl(argv); /* gid */ 825 cred->cr_gid = make_kgid(&init_user_ns, svc_getnl(argv)); /* gid */
826 if (!uid_valid(cred->cr_uid) || !gid_valid(cred->cr_gid))
827 goto badcred;
817 slen = svc_getnl(argv); /* gids length */ 828 slen = svc_getnl(argv); /* gids length */
818 if (slen > 16 || (len -= (slen + 2)*4) < 0) 829 if (slen > 16 || (len -= (slen + 2)*4) < 0)
819 goto badcred; 830 goto badcred;