diff options
| author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2012-07-24 22:43:04 -0700 | 
|---|---|---|
| committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2012-07-24 22:43:04 -0700 | 
| commit | 314820c9e892d8f41ba4db300ec96770d9c8294b (patch) | |
| tree | 3d5c59a429239b180c77e57f998a78d3f2b79827 /net/sunrpc/svcauth_unix.c | |
| parent | e76b8ee25e034ab601b525abb95cea14aa167ed3 (diff) | |
| parent | 07b8481d4aff73d6f451f25e74ea10240ff5131e (diff) | |
Merge branch 'next' into for-linus
Diffstat (limited to 'net/sunrpc/svcauth_unix.c')
| -rw-r--r-- | net/sunrpc/svcauth_unix.c | 37 | 
1 files changed, 22 insertions, 15 deletions
| diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c index 521d8f7dc83..2777fa89664 100644 --- a/net/sunrpc/svcauth_unix.c +++ b/net/sunrpc/svcauth_unix.c @@ -14,6 +14,7 @@  #include <net/sock.h>  #include <net/ipv6.h>  #include <linux/kernel.h> +#include <linux/user_namespace.h>  #define RPCDBG_FACILITY	RPCDBG_AUTH  #include <linux/sunrpc/clnt.h> @@ -346,17 +347,12 @@ static inline int ip_map_update(struct net *net, struct ip_map *ipm,  	return __ip_map_update(sn->ip_map_cache, ipm, udom, expiry);  } - -void svcauth_unix_purge(void) +void svcauth_unix_purge(struct net *net)  { -	struct net *net; - -	for_each_net(net) { -		struct sunrpc_net *sn; +	struct sunrpc_net *sn; -		sn = net_generic(net, sunrpc_net_id); -		cache_purge(sn->ip_map_cache); -	} +	sn = net_generic(net, sunrpc_net_id); +	cache_purge(sn->ip_map_cache);  }  EXPORT_SYMBOL_GPL(svcauth_unix_purge); @@ -530,11 +526,15 @@ static int unix_gid_parse(struct cache_detail *cd,  	for (i = 0 ; i < gids ; i++) {  		int gid; +		kgid_t kgid;  		rv = get_int(&mesg, &gid);  		err = -EINVAL;  		if (rv)  			goto out; -		GROUP_AT(ug.gi, i) = gid; +		kgid = make_kgid(&init_user_ns, gid); +		if (!gid_valid(kgid)) +			goto out; +		GROUP_AT(ug.gi, i) = kgid;  	}  	ugp = unix_gid_lookup(cd, uid); @@ -563,6 +563,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 unix_gid *ug;  	int i;  	int glen; @@ -580,7 +581,7 @@ static int unix_gid_show(struct seq_file *m,  	seq_printf(m, "%u %d:", ug->uid, glen);  	for (i = 0; i < glen; i++) -		seq_printf(m, " %d", GROUP_AT(ug->gi, i)); +		seq_printf(m, " %d", from_kgid_munged(user_ns, GROUP_AT(ug->gi, i)));  	seq_printf(m, "\n");  	return 0;  } @@ -745,6 +746,7 @@ svcauth_null_accept(struct svc_rqst *rqstp, __be32 *authp)  	struct svc_cred	*cred = &rqstp->rq_cred;  	cred->cr_group_info = NULL; +	cred->cr_principal = NULL;  	rqstp->rq_client = NULL;  	if (argv->iov_len < 3*4) @@ -772,7 +774,7 @@ svcauth_null_accept(struct svc_rqst *rqstp, __be32 *authp)  	svc_putnl(resv, RPC_AUTH_NULL);  	svc_putnl(resv, 0); -	rqstp->rq_flavor = RPC_AUTH_NULL; +	rqstp->rq_cred.cr_flavor = RPC_AUTH_NULL;  	return SVC_OK;  } @@ -810,6 +812,7 @@ svcauth_unix_accept(struct svc_rqst *rqstp, __be32 *authp)  	int		len   = argv->iov_len;  	cred->cr_group_info = NULL; +	cred->cr_principal = NULL;  	rqstp->rq_client = NULL;  	if ((len -= 3*4) < 0) @@ -831,8 +834,12 @@ svcauth_unix_accept(struct svc_rqst *rqstp, __be32 *authp)  	cred->cr_group_info = groups_alloc(slen);  	if (cred->cr_group_info == NULL)  		return SVC_CLOSE; -	for (i = 0; i < slen; i++) -		GROUP_AT(cred->cr_group_info, i) = svc_getnl(argv); +	for (i = 0; i < slen; i++) { +		kgid_t kgid = make_kgid(&init_user_ns, svc_getnl(argv)); +		if (!gid_valid(kgid)) +			goto badcred; +		GROUP_AT(cred->cr_group_info, i) = kgid; +	}  	if (svc_getu32(argv) != htonl(RPC_AUTH_NULL) || svc_getu32(argv) != 0) {  		*authp = rpc_autherr_badverf;  		return SVC_DENIED; @@ -842,7 +849,7 @@ svcauth_unix_accept(struct svc_rqst *rqstp, __be32 *authp)  	svc_putnl(resv, RPC_AUTH_NULL);  	svc_putnl(resv, 0); -	rqstp->rq_flavor = RPC_AUTH_UNIX; +	rqstp->rq_cred.cr_flavor = RPC_AUTH_UNIX;  	return SVC_OK;  badcred: | 
