diff options
| author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2007-06-07 10:14:15 -0400 |
|---|---|---|
| committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2007-07-10 23:40:31 -0400 |
| commit | 3b68aaeaf54065e5c44583a1d33ffb7793953ba4 (patch) | |
| tree | 7b2e142d018fece125cc6616c117af575a8c095b /net/sunrpc | |
| parent | b185f835e243e654047ae85f42346827d3894171 (diff) | |
SUNRPC: Always match an upcall message in gss_pipe_downcall()
It used to be possible for an rpc.gssd daemon to stuff the RPC credential
cache for any rpc client simply by creating RPCSEC_GSS contexts and then
doing downcalls. In practice, no daemons ever made use of this feature.
Remove this feature now, since it will be impossible to figure out which
mechanism a given context actually matches if we enable more
than one gss mechanism to use the same upcall pipe.
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'net/sunrpc')
| -rw-r--r-- | net/sunrpc/auth_gss/auth_gss.c | 58 |
1 files changed, 27 insertions, 31 deletions
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c index 653d712a1ffb..e407a352440f 100644 --- a/net/sunrpc/auth_gss/auth_gss.c +++ b/net/sunrpc/auth_gss/auth_gss.c | |||
| @@ -306,8 +306,6 @@ gss_add_msg(struct gss_auth *gss_auth, struct gss_upcall_msg *gss_msg) | |||
| 306 | static void | 306 | static void |
| 307 | __gss_unhash_msg(struct gss_upcall_msg *gss_msg) | 307 | __gss_unhash_msg(struct gss_upcall_msg *gss_msg) |
| 308 | { | 308 | { |
| 309 | if (list_empty(&gss_msg->list)) | ||
| 310 | return; | ||
| 311 | list_del_init(&gss_msg->list); | 309 | list_del_init(&gss_msg->list); |
| 312 | rpc_wake_up_status(&gss_msg->rpc_waitqueue, gss_msg->msg.errno); | 310 | rpc_wake_up_status(&gss_msg->rpc_waitqueue, gss_msg->msg.errno); |
| 313 | wake_up_all(&gss_msg->waitqueue); | 311 | wake_up_all(&gss_msg->waitqueue); |
| @@ -320,8 +318,11 @@ gss_unhash_msg(struct gss_upcall_msg *gss_msg) | |||
| 320 | struct gss_auth *gss_auth = gss_msg->auth; | 318 | struct gss_auth *gss_auth = gss_msg->auth; |
| 321 | struct inode *inode = gss_auth->dentry->d_inode; | 319 | struct inode *inode = gss_auth->dentry->d_inode; |
| 322 | 320 | ||
| 321 | if (list_empty(&gss_msg->list)) | ||
| 322 | return; | ||
| 323 | spin_lock(&inode->i_lock); | 323 | spin_lock(&inode->i_lock); |
| 324 | __gss_unhash_msg(gss_msg); | 324 | if (!list_empty(&gss_msg->list)) |
| 325 | __gss_unhash_msg(gss_msg); | ||
| 325 | spin_unlock(&inode->i_lock); | 326 | spin_unlock(&inode->i_lock); |
| 326 | } | 327 | } |
| 327 | 328 | ||
| @@ -493,12 +494,11 @@ gss_pipe_downcall(struct file *filp, const char __user *src, size_t mlen) | |||
| 493 | void *buf; | 494 | void *buf; |
| 494 | struct rpc_clnt *clnt; | 495 | struct rpc_clnt *clnt; |
| 495 | struct gss_auth *gss_auth; | 496 | struct gss_auth *gss_auth; |
| 496 | struct rpc_cred *cred; | ||
| 497 | struct gss_upcall_msg *gss_msg; | 497 | struct gss_upcall_msg *gss_msg; |
| 498 | struct inode *inode = filp->f_path.dentry->d_inode; | 498 | struct inode *inode = filp->f_path.dentry->d_inode; |
| 499 | struct gss_cl_ctx *ctx; | 499 | struct gss_cl_ctx *ctx; |
| 500 | uid_t uid; | 500 | uid_t uid; |
| 501 | int err = -EFBIG; | 501 | ssize_t err = -EFBIG; |
| 502 | 502 | ||
| 503 | if (mlen > MSG_BUF_MAXSIZE) | 503 | if (mlen > MSG_BUF_MAXSIZE) |
| 504 | goto out; | 504 | goto out; |
| @@ -523,43 +523,39 @@ gss_pipe_downcall(struct file *filp, const char __user *src, size_t mlen) | |||
| 523 | ctx = gss_alloc_context(); | 523 | ctx = gss_alloc_context(); |
| 524 | if (ctx == NULL) | 524 | if (ctx == NULL) |
| 525 | goto err; | 525 | goto err; |
| 526 | err = 0; | 526 | |
| 527 | err = -ENOENT; | ||
| 528 | /* Find a matching upcall */ | ||
| 527 | gss_auth = container_of(clnt->cl_auth, struct gss_auth, rpc_auth); | 529 | gss_auth = container_of(clnt->cl_auth, struct gss_auth, rpc_auth); |
| 530 | spin_lock(&inode->i_lock); | ||
| 531 | gss_msg = __gss_find_upcall(gss_auth, uid); | ||
| 532 | if (gss_msg == NULL) { | ||
| 533 | spin_unlock(&inode->i_lock); | ||
| 534 | goto err_put_ctx; | ||
| 535 | } | ||
| 536 | list_del_init(&gss_msg->list); | ||
| 537 | spin_unlock(&inode->i_lock); | ||
| 538 | |||
| 528 | p = gss_fill_context(p, end, ctx, gss_auth->mech); | 539 | p = gss_fill_context(p, end, ctx, gss_auth->mech); |
| 529 | if (IS_ERR(p)) { | 540 | if (IS_ERR(p)) { |
| 530 | err = PTR_ERR(p); | 541 | err = PTR_ERR(p); |
| 531 | if (err != -EACCES) | 542 | gss_msg->msg.errno = (err == -EACCES) ? -EACCES : -EAGAIN; |
| 532 | goto err_put_ctx; | 543 | goto err_release_msg; |
| 533 | } | 544 | } |
| 545 | gss_msg->ctx = gss_get_ctx(ctx); | ||
| 546 | err = mlen; | ||
| 547 | |||
| 548 | err_release_msg: | ||
| 534 | spin_lock(&inode->i_lock); | 549 | spin_lock(&inode->i_lock); |
| 535 | gss_msg = __gss_find_upcall(gss_auth, uid); | 550 | __gss_unhash_msg(gss_msg); |
| 536 | if (gss_msg) { | 551 | spin_unlock(&inode->i_lock); |
| 537 | if (err == 0 && gss_msg->ctx == NULL) | 552 | gss_release_msg(gss_msg); |
| 538 | gss_msg->ctx = gss_get_ctx(ctx); | ||
| 539 | gss_msg->msg.errno = err; | ||
| 540 | __gss_unhash_msg(gss_msg); | ||
| 541 | spin_unlock(&inode->i_lock); | ||
| 542 | gss_release_msg(gss_msg); | ||
| 543 | } else { | ||
| 544 | struct auth_cred acred = { .uid = uid }; | ||
| 545 | spin_unlock(&inode->i_lock); | ||
| 546 | cred = rpcauth_lookup_credcache(clnt->cl_auth, &acred, RPCAUTH_LOOKUP_NEW); | ||
| 547 | if (IS_ERR(cred)) { | ||
| 548 | err = PTR_ERR(cred); | ||
| 549 | goto err_put_ctx; | ||
| 550 | } | ||
| 551 | gss_cred_set_ctx(cred, gss_get_ctx(ctx)); | ||
| 552 | } | ||
| 553 | gss_put_ctx(ctx); | ||
| 554 | kfree(buf); | ||
| 555 | dprintk("RPC: gss_pipe_downcall returning length %Zu\n", mlen); | ||
| 556 | return mlen; | ||
| 557 | err_put_ctx: | 553 | err_put_ctx: |
| 558 | gss_put_ctx(ctx); | 554 | gss_put_ctx(ctx); |
| 559 | err: | 555 | err: |
| 560 | kfree(buf); | 556 | kfree(buf); |
| 561 | out: | 557 | out: |
| 562 | dprintk("RPC: gss_pipe_downcall returning %d\n", err); | 558 | dprintk("RPC: gss_pipe_downcall returning %Zd\n", err); |
| 563 | return err; | 559 | return err; |
| 564 | } | 560 | } |
| 565 | 561 | ||
