diff options
author | Eric W. Biederman <ebiederm@xmission.com> | 2013-02-02 05:49:44 -0500 |
---|---|---|
committer | Eric W. Biederman <ebiederm@xmission.com> | 2013-02-13 09:15:25 -0500 |
commit | 25da9263710ec94c964259c79fa9a3a635cd3a50 (patch) | |
tree | c2f3aed2f7517c1c046d9ef331aad2926e195200 | |
parent | a570abbb966ee7de6c4357a58be11a558fa7099b (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>
-rw-r--r-- | net/sunrpc/svcauth_unix.c | 14 |
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"); |