Commit ac83228a authored by Trond Myklebust's avatar Trond Myklebust Committed by Anna Schumaker

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: default avatarTrond Myklebust <trond.myklebust@hammerspace.com>
Signed-off-by: default avatarAnna Schumaker <Anna.Schumaker@Netapp.com>
parent 283ebe3e
...@@ -269,6 +269,7 @@ gss_fill_context(const void *p, const void *end, struct gss_cl_ctx *ctx, struct ...@@ -269,6 +269,7 @@ gss_fill_context(const void *p, const void *end, struct gss_cl_ctx *ctx, struct
struct gss_upcall_msg { struct gss_upcall_msg {
refcount_t count; refcount_t count;
kuid_t uid; kuid_t uid;
const char *service_name;
struct rpc_pipe_msg msg; struct rpc_pipe_msg msg;
struct list_head list; struct list_head list;
struct gss_auth *auth; struct gss_auth *auth;
...@@ -316,6 +317,7 @@ gss_release_msg(struct gss_upcall_msg *gss_msg) ...@@ -316,6 +317,7 @@ gss_release_msg(struct gss_upcall_msg *gss_msg)
gss_put_ctx(gss_msg->ctx); gss_put_ctx(gss_msg->ctx);
rpc_destroy_wait_queue(&gss_msg->rpc_waitqueue); rpc_destroy_wait_queue(&gss_msg->rpc_waitqueue);
gss_put_auth(gss_msg->auth); gss_put_auth(gss_msg->auth);
kfree_const(gss_msg->service_name);
kfree(gss_msg); kfree(gss_msg);
} }
...@@ -410,10 +412,10 @@ gss_upcall_callback(struct rpc_task *task) ...@@ -410,10 +412,10 @@ gss_upcall_callback(struct rpc_task *task)
gss_release_msg(gss_msg); 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 ? struct user_namespace *userns = cred->user_ns;
gss_msg->auth->client->cl_cred->user_ns : &init_user_ns;
uid_t uid = from_kuid_munged(userns, gss_msg->uid); uid_t uid = from_kuid_munged(userns, gss_msg->uid);
memcpy(gss_msg->databuf, &uid, sizeof(uid)); memcpy(gss_msg->databuf, &uid, sizeof(uid));
...@@ -423,12 +425,24 @@ static void gss_encode_v0_msg(struct gss_upcall_msg *gss_msg) ...@@ -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)); 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, static int gss_encode_v1_msg(struct gss_upcall_msg *gss_msg,
const char *service_name, 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 ? struct user_namespace *userns = cred->user_ns;
gss_msg->auth->client->cl_cred->user_ns : &init_user_ns;
struct gss_api_mech *mech = gss_msg->auth->mech; struct gss_api_mech *mech = gss_msg->auth->mech;
char *p = gss_msg->databuf; char *p = gss_msg->databuf;
size_t buflen = sizeof(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, ...@@ -496,6 +510,25 @@ static int gss_encode_v1_msg(struct gss_upcall_msg *gss_msg,
return -ENOMEM; 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 * static struct gss_upcall_msg *
gss_alloc_msg(struct gss_auth *gss_auth, gss_alloc_msg(struct gss_auth *gss_auth,
kuid_t uid, const char *service_name) kuid_t uid, const char *service_name)
...@@ -518,16 +551,11 @@ gss_alloc_msg(struct gss_auth *gss_auth, ...@@ -518,16 +551,11 @@ gss_alloc_msg(struct gss_auth *gss_auth,
refcount_set(&gss_msg->count, 1); refcount_set(&gss_msg->count, 1);
gss_msg->uid = uid; gss_msg->uid = uid;
gss_msg->auth = gss_auth; gss_msg->auth = gss_auth;
switch (vers) { if (service_name) {
case 0: gss_msg->service_name = kstrdup_const(service_name, GFP_NOFS);
gss_encode_v0_msg(gss_msg); if (!gss_msg->service_name)
break;
default:
err = gss_encode_v1_msg(gss_msg, service_name, gss_auth->target_name);
if (err)
goto err_put_pipe_version; goto err_put_pipe_version;
} }
kref_get(&gss_auth->kref);
return gss_msg; return gss_msg;
err_put_pipe_version: err_put_pipe_version:
put_pipe_version(gss_auth->net); put_pipe_version(gss_auth->net);
...@@ -2120,7 +2148,7 @@ static const struct rpc_credops gss_nullops = { ...@@ -2120,7 +2148,7 @@ static const struct rpc_credops gss_nullops = {
}; };
static const struct rpc_pipe_ops gss_upcall_ops_v0 = { static const struct rpc_pipe_ops gss_upcall_ops_v0 = {
.upcall = rpc_pipe_generic_upcall, .upcall = gss_v0_upcall,
.downcall = gss_pipe_downcall, .downcall = gss_pipe_downcall,
.destroy_msg = gss_pipe_destroy_msg, .destroy_msg = gss_pipe_destroy_msg,
.open_pipe = gss_pipe_open_v0, .open_pipe = gss_pipe_open_v0,
...@@ -2128,7 +2156,7 @@ static const struct rpc_pipe_ops gss_upcall_ops_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 = { static const struct rpc_pipe_ops gss_upcall_ops_v1 = {
.upcall = rpc_pipe_generic_upcall, .upcall = gss_v1_upcall,
.downcall = gss_pipe_downcall, .downcall = gss_pipe_downcall,
.destroy_msg = gss_pipe_destroy_msg, .destroy_msg = gss_pipe_destroy_msg,
.open_pipe = gss_pipe_open_v1, .open_pipe = gss_pipe_open_v1,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment