Skip to content

Commit

Permalink
SUNRPC: Use namespace of listening daemon in the client AUTH_GSS upcall
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Trond Myklebust authored and Anna Schumaker committed Apr 26, 2019
1 parent 283ebe3 commit ac83228
Showing 1 changed file with 44 additions and 16 deletions.
60 changes: 44 additions & 16 deletions net/sunrpc/auth_gss/auth_gss.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
}

Expand Down Expand Up @@ -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));
Expand All @@ -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);
Expand Down Expand Up @@ -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)
Expand All @@ -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);
Expand Down Expand Up @@ -2120,15 +2148,15 @@ 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,
.release_pipe = gss_pipe_release,
};

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,
Expand Down

0 comments on commit ac83228

Please sign in to comment.