path: root/net/sunrpc
diff options
authorEric W. Biederman <ebiederm@xmission.com>2013-02-02 02:49:44 -0800
committerEric W. Biederman <ebiederm@xmission.com>2013-02-13 06:15:25 -0800
commit25da9263710ec94c964259c79fa9a3a635cd3a50 (patch)
treec2f3aed2f7517c1c046d9ef331aad2926e195200 /net/sunrpc
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')
1 files changed, 9 insertions, 5 deletions
diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c
index faf17195a9f..bdea0a1b6d1 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,
char tuid[20];
struct unix_gid *ug = container_of(h, struct unix_gid, h);
- snprintf(tuid, 20, "%u", ug->uid);
+ snprintf(tuid, 20, "%u", from_kuid(&init_user_ns, ug->uid));
qword_add(bpp, blen, tuid);
(*bpp)[-1] = '\n';
@@ -486,7 +486,8 @@ static int unix_gid_parse(struct cache_detail *cd,
char *mesg, int mlen)
/* uid expiry Ngid gid0 gid1 ... gidN-1 */
- int uid;
+ int id;
+ kuid_t uid;
int gids;
int rv;
int i;
@@ -498,9 +499,12 @@ static int unix_gid_parse(struct cache_detail *cd,
return -EINVAL;
mesg[mlen-1] = 0;
- rv = get_int(&mesg, &uid);
+ rv = get_int(&mesg, &id);
if (rv)
return -EINVAL;
+ uid = make_kuid(&init_user_ns, id);
+ if (!uid_valid(uid))
+ return -EINVAL;
ug.uid = uid;
expiry = get_expiry(&mesg);
@@ -554,7 +558,7 @@ static int unix_gid_show(struct seq_file *m,
struct cache_detail *cd,
struct cache_head *h)
- struct user_namespace *user_ns = current_user_ns();
+ struct user_namespace *user_ns = &init_user_ns;
struct unix_gid *ug;
int i;
int glen;
@@ -570,7 +574,7 @@ static int unix_gid_show(struct seq_file *m,
glen = 0;
- seq_printf(m, "%u %d:", ug->uid, glen);
+ seq_printf(m, "%u %d:", from_kuid_munged(user_ns, ug->uid), glen);
for (i = 0; i < glen; i++)
seq_printf(m, " %d", from_kgid_munged(user_ns, GROUP_AT(ug->gi, i)));
seq_printf(m, "\n");