aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc/svcauth_unix.c
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2013-02-02 05:49:44 -0500
committerEric W. Biederman <ebiederm@xmission.com>2013-02-13 09:15:25 -0500
commit25da9263710ec94c964259c79fa9a3a635cd3a50 (patch)
treec2f3aed2f7517c1c046d9ef331aad2926e195200 /net/sunrpc/svcauth_unix.c
parenta570abbb966ee7de6c4357a58be11a558fa7099b (diff)
sunrpc: Properly encode kuids and kgids in auth.unix.gid rpc pipe upcalls.
When a new rpc connection is established with an in-kernel server, the traffic passes through svc_process_common, and svc_set_client and down into svcauth_unix_set_client if it is of type RPC_AUTH_NULL or RPC_AUTH_UNIX. svcauth_unix_set_client then looks at the uid of the credential we have assigned to the incomming client and if we don't have the groups already cached makes an upcall to get a list of groups that the client can use. The upcall encodes send a rpc message to user space encoding the uid of the user whose groups we want to know. Encode the kuid of the user in the initial user namespace as nfs mounts can only happen today in the initial user namespace. When a reply to an upcall comes in convert interpret the uid and gid values from the rpc pipe as uids and gids in the initial user namespace and convert them into kuids and kgids before processing them further. When reading proc files listing the uid to gid list cache convert the kuids and kgids from into uids and gids the initial user namespace. As we are displaying server internal details it makes sense to display these values from the servers perspective. Cc: "J. Bruce Fields" <bfields@fieldses.org> Cc: Trond Myklebust <Trond.Myklebust@netapp.com> Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
Diffstat (limited to 'net/sunrpc/svcauth_unix.c')
-rw-r--r--net/sunrpc/svcauth_unix.c14
1 files changed, 9 insertions, 5 deletions
diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c
index faf17195a9fd..bdea0a1b6d1d 100644
--- a/net/sunrpc/svcauth_unix.c
+++ b/net/sunrpc/svcauth_unix.c
@@ -470,7 +470,7 @@ static void unix_gid_request(struct cache_detail *cd,
470 char tuid[20]; 470 char tuid[20];
471 struct unix_gid *ug = container_of(h, struct unix_gid, h); 471 struct unix_gid *ug = container_of(h, struct unix_gid, h);
472 472
473 snprintf(tuid, 20, "%u", ug->uid); 473 snprintf(tuid, 20, "%u", from_kuid(&init_user_ns, ug->uid));
474 qword_add(bpp, blen, tuid); 474 qword_add(bpp, blen, tuid);
475 (*bpp)[-1] = '\n'; 475 (*bpp)[-1] = '\n';
476} 476}
@@ -486,7 +486,8 @@ static int unix_gid_parse(struct cache_detail *cd,
486 char *mesg, int mlen) 486 char *mesg, int mlen)
487{ 487{
488 /* uid expiry Ngid gid0 gid1 ... gidN-1 */ 488 /* uid expiry Ngid gid0 gid1 ... gidN-1 */
489 int uid; 489 int id;
490 kuid_t uid;
490 int gids; 491 int gids;
491 int rv; 492 int rv;
492 int i; 493 int i;
@@ -498,9 +499,12 @@ static int unix_gid_parse(struct cache_detail *cd,
498 return -EINVAL; 499 return -EINVAL;
499 mesg[mlen-1] = 0; 500 mesg[mlen-1] = 0;
500 501
501 rv = get_int(&mesg, &uid); 502 rv = get_int(&mesg, &id);
502 if (rv) 503 if (rv)
503 return -EINVAL; 504 return -EINVAL;
505 uid = make_kuid(&init_user_ns, id);
506 if (!uid_valid(uid))
507 return -EINVAL;
504 ug.uid = uid; 508 ug.uid = uid;
505 509
506 expiry = get_expiry(&mesg); 510 expiry = get_expiry(&mesg);
@@ -554,7 +558,7 @@ static int unix_gid_show(struct seq_file *m,
554 struct cache_detail *cd, 558 struct cache_detail *cd,
555 struct cache_head *h) 559 struct cache_head *h)
556{ 560{
557 struct user_namespace *user_ns = current_user_ns(); 561 struct user_namespace *user_ns = &init_user_ns;
558 struct unix_gid *ug; 562 struct unix_gid *ug;
559 int i; 563 int i;
560 int glen; 564 int glen;
@@ -570,7 +574,7 @@ static int unix_gid_show(struct seq_file *m,
570 else 574 else
571 glen = 0; 575 glen = 0;
572 576
573 seq_printf(m, "%u %d:", ug->uid, glen); 577 seq_printf(m, "%u %d:", from_kuid_munged(user_ns, ug->uid), glen);
574 for (i = 0; i < glen; i++) 578 for (i = 0; i < glen; i++)
575 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)));
576 seq_printf(m, "\n"); 580 seq_printf(m, "\n");