mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	SUNRPC: Use namespace of listening daemon in the client AUTH_GSS upcall
When the client needs to talk to rpc.gssd, we should ensure that the uid argument is encoded to match the user namespace of the daemon. Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
This commit is contained in:
		
							parent
							
								
									283ebe3ec4
								
							
						
					
					
						commit
						ac83228a71
					
				
					 1 changed files with 44 additions and 16 deletions
				
			
		| 
						 | 
				
			
			@ -269,6 +269,7 @@ gss_fill_context(const void *p, const void *end, struct gss_cl_ctx *ctx, struct
 | 
			
		|||
struct gss_upcall_msg {
 | 
			
		||||
	refcount_t count;
 | 
			
		||||
	kuid_t	uid;
 | 
			
		||||
	const char *service_name;
 | 
			
		||||
	struct rpc_pipe_msg msg;
 | 
			
		||||
	struct list_head list;
 | 
			
		||||
	struct gss_auth *auth;
 | 
			
		||||
| 
						 | 
				
			
			@ -316,6 +317,7 @@ gss_release_msg(struct gss_upcall_msg *gss_msg)
 | 
			
		|||
		gss_put_ctx(gss_msg->ctx);
 | 
			
		||||
	rpc_destroy_wait_queue(&gss_msg->rpc_waitqueue);
 | 
			
		||||
	gss_put_auth(gss_msg->auth);
 | 
			
		||||
	kfree_const(gss_msg->service_name);
 | 
			
		||||
	kfree(gss_msg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -410,10 +412,10 @@ gss_upcall_callback(struct rpc_task *task)
 | 
			
		|||
	gss_release_msg(gss_msg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void gss_encode_v0_msg(struct gss_upcall_msg *gss_msg)
 | 
			
		||||
static void gss_encode_v0_msg(struct gss_upcall_msg *gss_msg,
 | 
			
		||||
			      const struct cred *cred)
 | 
			
		||||
{
 | 
			
		||||
	struct user_namespace *userns = gss_msg->auth->client->cl_cred ?
 | 
			
		||||
		gss_msg->auth->client->cl_cred->user_ns : &init_user_ns;
 | 
			
		||||
	struct user_namespace *userns = cred->user_ns;
 | 
			
		||||
 | 
			
		||||
	uid_t uid = from_kuid_munged(userns, gss_msg->uid);
 | 
			
		||||
	memcpy(gss_msg->databuf, &uid, sizeof(uid));
 | 
			
		||||
| 
						 | 
				
			
			@ -423,12 +425,24 @@ static void gss_encode_v0_msg(struct gss_upcall_msg *gss_msg)
 | 
			
		|||
	BUILD_BUG_ON(sizeof(uid) > sizeof(gss_msg->databuf));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static ssize_t
 | 
			
		||||
gss_v0_upcall(struct file *file, struct rpc_pipe_msg *msg,
 | 
			
		||||
		char __user *buf, size_t buflen)
 | 
			
		||||
{
 | 
			
		||||
	struct gss_upcall_msg *gss_msg = container_of(msg,
 | 
			
		||||
						      struct gss_upcall_msg,
 | 
			
		||||
						      msg);
 | 
			
		||||
	if (msg->copied == 0)
 | 
			
		||||
		gss_encode_v0_msg(gss_msg, file->f_cred);
 | 
			
		||||
	return rpc_pipe_generic_upcall(file, msg, buf, buflen);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int gss_encode_v1_msg(struct gss_upcall_msg *gss_msg,
 | 
			
		||||
				const char *service_name,
 | 
			
		||||
				const char *target_name)
 | 
			
		||||
				const char *target_name,
 | 
			
		||||
				const struct cred *cred)
 | 
			
		||||
{
 | 
			
		||||
	struct user_namespace *userns = gss_msg->auth->client->cl_cred ?
 | 
			
		||||
		gss_msg->auth->client->cl_cred->user_ns : &init_user_ns;
 | 
			
		||||
	struct user_namespace *userns = cred->user_ns;
 | 
			
		||||
	struct gss_api_mech *mech = gss_msg->auth->mech;
 | 
			
		||||
	char *p = gss_msg->databuf;
 | 
			
		||||
	size_t buflen = sizeof(gss_msg->databuf);
 | 
			
		||||
| 
						 | 
				
			
			@ -496,6 +510,25 @@ static int gss_encode_v1_msg(struct gss_upcall_msg *gss_msg,
 | 
			
		|||
	return -ENOMEM;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static ssize_t
 | 
			
		||||
gss_v1_upcall(struct file *file, struct rpc_pipe_msg *msg,
 | 
			
		||||
		char __user *buf, size_t buflen)
 | 
			
		||||
{
 | 
			
		||||
	struct gss_upcall_msg *gss_msg = container_of(msg,
 | 
			
		||||
						      struct gss_upcall_msg,
 | 
			
		||||
						      msg);
 | 
			
		||||
	int err;
 | 
			
		||||
	if (msg->copied == 0) {
 | 
			
		||||
		err = gss_encode_v1_msg(gss_msg,
 | 
			
		||||
					gss_msg->service_name,
 | 
			
		||||
					gss_msg->auth->target_name,
 | 
			
		||||
					file->f_cred);
 | 
			
		||||
		if (err)
 | 
			
		||||
			return err;
 | 
			
		||||
	}
 | 
			
		||||
	return rpc_pipe_generic_upcall(file, msg, buf, buflen);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static struct gss_upcall_msg *
 | 
			
		||||
gss_alloc_msg(struct gss_auth *gss_auth,
 | 
			
		||||
		kuid_t uid, const char *service_name)
 | 
			
		||||
| 
						 | 
				
			
			@ -518,16 +551,11 @@ gss_alloc_msg(struct gss_auth *gss_auth,
 | 
			
		|||
	refcount_set(&gss_msg->count, 1);
 | 
			
		||||
	gss_msg->uid = uid;
 | 
			
		||||
	gss_msg->auth = gss_auth;
 | 
			
		||||
	switch (vers) {
 | 
			
		||||
	case 0:
 | 
			
		||||
		gss_encode_v0_msg(gss_msg);
 | 
			
		||||
		break;
 | 
			
		||||
	default:
 | 
			
		||||
		err = gss_encode_v1_msg(gss_msg, service_name, gss_auth->target_name);
 | 
			
		||||
		if (err)
 | 
			
		||||
	if (service_name) {
 | 
			
		||||
		gss_msg->service_name = kstrdup_const(service_name, GFP_NOFS);
 | 
			
		||||
		if (!gss_msg->service_name)
 | 
			
		||||
			goto err_put_pipe_version;
 | 
			
		||||
	}
 | 
			
		||||
	kref_get(&gss_auth->kref);
 | 
			
		||||
	return gss_msg;
 | 
			
		||||
err_put_pipe_version:
 | 
			
		||||
	put_pipe_version(gss_auth->net);
 | 
			
		||||
| 
						 | 
				
			
			@ -2120,7 +2148,7 @@ static const struct rpc_credops gss_nullops = {
 | 
			
		|||
};
 | 
			
		||||
 | 
			
		||||
static const struct rpc_pipe_ops gss_upcall_ops_v0 = {
 | 
			
		||||
	.upcall		= rpc_pipe_generic_upcall,
 | 
			
		||||
	.upcall		= gss_v0_upcall,
 | 
			
		||||
	.downcall	= gss_pipe_downcall,
 | 
			
		||||
	.destroy_msg	= gss_pipe_destroy_msg,
 | 
			
		||||
	.open_pipe	= gss_pipe_open_v0,
 | 
			
		||||
| 
						 | 
				
			
			@ -2128,7 +2156,7 @@ static const struct rpc_pipe_ops gss_upcall_ops_v0 = {
 | 
			
		|||
};
 | 
			
		||||
 | 
			
		||||
static const struct rpc_pipe_ops gss_upcall_ops_v1 = {
 | 
			
		||||
	.upcall		= rpc_pipe_generic_upcall,
 | 
			
		||||
	.upcall		= gss_v1_upcall,
 | 
			
		||||
	.downcall	= gss_pipe_downcall,
 | 
			
		||||
	.destroy_msg	= gss_pipe_destroy_msg,
 | 
			
		||||
	.open_pipe	= gss_pipe_open_v1,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue