aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2007-06-27 14:29:12 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2007-07-10 23:40:37 -0400
commit0285ed1f12298e5304f0f2642e2cf31a5f302e61 (patch)
treeafc4f0829fcbe910c60a89d03c2ea99f71eb78b6
parent1be27f36601973815171db684c711d30557cf50c (diff)
SUNRPC: Ensure that the struct gss_auth lifetime exceeds the credential's
Add a refcount in order to ensure that the gss_auth doesn't disappear from underneath us while we're freeing up GSS contexts. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
-rw-r--r--net/sunrpc/auth_gss/auth_gss.c31
1 files changed, 25 insertions, 6 deletions
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
index debcda86467c..982aba697e4d 100644
--- a/net/sunrpc/auth_gss/auth_gss.c
+++ b/net/sunrpc/auth_gss/auth_gss.c
@@ -79,6 +79,7 @@ static const struct rpc_credops gss_credops;
79#define isprint(c) ((c > 0x1f) && (c < 0x7f)) 79#define isprint(c) ((c > 0x1f) && (c < 0x7f))
80 80
81struct gss_auth { 81struct gss_auth {
82 struct kref kref;
82 struct rpc_auth rpc_auth; 83 struct rpc_auth rpc_auth;
83 struct gss_api_mech *mech; 84 struct gss_api_mech *mech;
84 enum rpc_gss_svc service; 85 enum rpc_gss_svc service;
@@ -636,6 +637,7 @@ gss_create(struct rpc_clnt *clnt, rpc_authflavor_t flavor)
636 auth->au_ops = &authgss_ops; 637 auth->au_ops = &authgss_ops;
637 auth->au_flavor = flavor; 638 auth->au_flavor = flavor;
638 atomic_set(&auth->au_count, 1); 639 atomic_set(&auth->au_count, 1);
640 kref_init(&gss_auth->kref);
639 641
640 gss_auth->dentry = rpc_mkpipe(clnt->cl_dentry, gss_auth->mech->gm_name, 642 gss_auth->dentry = rpc_mkpipe(clnt->cl_dentry, gss_auth->mech->gm_name,
641 clnt, &gss_upcall_ops, RPC_PIPE_WAIT_FOR_OPEN); 643 clnt, &gss_upcall_ops, RPC_PIPE_WAIT_FOR_OPEN);
@@ -661,6 +663,25 @@ out_dec:
661} 663}
662 664
663static void 665static void
666gss_free(struct gss_auth *gss_auth)
667{
668 rpc_unlink(gss_auth->dentry);
669 gss_auth->dentry = NULL;
670 gss_mech_put(gss_auth->mech);
671
672 kfree(gss_auth);
673 module_put(THIS_MODULE);
674}
675
676static void
677gss_free_callback(struct kref *kref)
678{
679 struct gss_auth *gss_auth = container_of(kref, struct gss_auth, kref);
680
681 gss_free(gss_auth);
682}
683
684static void
664gss_destroy(struct rpc_auth *auth) 685gss_destroy(struct rpc_auth *auth)
665{ 686{
666 struct gss_auth *gss_auth; 687 struct gss_auth *gss_auth;
@@ -671,12 +692,7 @@ gss_destroy(struct rpc_auth *auth)
671 rpcauth_destroy_credcache(auth); 692 rpcauth_destroy_credcache(auth);
672 693
673 gss_auth = container_of(auth, struct gss_auth, rpc_auth); 694 gss_auth = container_of(auth, struct gss_auth, rpc_auth);
674 rpc_unlink(gss_auth->dentry); 695 kref_put(&gss_auth->kref, gss_free_callback);
675 gss_auth->dentry = NULL;
676 gss_mech_put(gss_auth->mech);
677
678 kfree(gss_auth);
679 module_put(THIS_MODULE);
680} 696}
681 697
682/* gss_destroy_cred (and gss_destroy_ctx) are used to clean up after failure 698/* gss_destroy_cred (and gss_destroy_ctx) are used to clean up after failure
@@ -725,12 +741,14 @@ static void
725gss_destroy_cred(struct rpc_cred *cred) 741gss_destroy_cred(struct rpc_cred *cred)
726{ 742{
727 struct gss_cred *gss_cred = container_of(cred, struct gss_cred, gc_base); 743 struct gss_cred *gss_cred = container_of(cred, struct gss_cred, gc_base);
744 struct gss_auth *gss_auth = container_of(cred->cr_auth, struct gss_auth, rpc_auth);
728 struct gss_cl_ctx *ctx = gss_cred->gc_ctx; 745 struct gss_cl_ctx *ctx = gss_cred->gc_ctx;
729 746
730 rcu_assign_pointer(gss_cred->gc_ctx, NULL); 747 rcu_assign_pointer(gss_cred->gc_ctx, NULL);
731 call_rcu(&cred->cr_rcu, gss_free_cred_callback); 748 call_rcu(&cred->cr_rcu, gss_free_cred_callback);
732 if (ctx) 749 if (ctx)
733 gss_put_ctx(ctx); 750 gss_put_ctx(ctx);
751 kref_put(&gss_auth->kref, gss_free_callback);
734} 752}
735 753
736/* 754/*
@@ -762,6 +780,7 @@ gss_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)
762 */ 780 */
763 cred->gc_base.cr_flags = 1UL << RPCAUTH_CRED_NEW; 781 cred->gc_base.cr_flags = 1UL << RPCAUTH_CRED_NEW;
764 cred->gc_service = gss_auth->service; 782 cred->gc_service = gss_auth->service;
783 kref_get(&gss_auth->kref);
765 return &cred->gc_base; 784 return &cred->gc_base;
766 785
767out_err: 786out_err: