SUNRPC: Fix a memory leak in the auth credcache code
The leak only affects the RPCSEC_GSS caches, since they are the only ones that are dynamically allocated... Rename the existing rpcauth_free_credcache() to rpcauth_clear_credcache() in order to better describe its role, then add a new function rpcauth_destroy_credcache() that actually frees the cache in addition to clearing it out. Also move the call to destroy the credcache in gss_destroy() to come before the rpc upcall pipe is unlinked. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
This commit is contained in:
Родитель
03a1256f06
Коммит
3ab9bb7243
|
@ -143,7 +143,8 @@ int rpcauth_refreshcred(struct rpc_task *);
|
|||
void rpcauth_invalcred(struct rpc_task *);
|
||||
int rpcauth_uptodatecred(struct rpc_task *);
|
||||
int rpcauth_init_credcache(struct rpc_auth *, unsigned long);
|
||||
void rpcauth_free_credcache(struct rpc_auth *);
|
||||
void rpcauth_destroy_credcache(struct rpc_auth *);
|
||||
void rpcauth_clear_credcache(struct rpc_cred_cache *);
|
||||
|
||||
static inline
|
||||
struct rpc_cred * get_rpccred(struct rpc_cred *cred)
|
||||
|
|
|
@ -137,9 +137,8 @@ void rpcauth_destroy_credlist(struct hlist_head *head)
|
|||
* that are not referenced.
|
||||
*/
|
||||
void
|
||||
rpcauth_free_credcache(struct rpc_auth *auth)
|
||||
rpcauth_clear_credcache(struct rpc_cred_cache *cache)
|
||||
{
|
||||
struct rpc_cred_cache *cache = auth->au_credcache;
|
||||
HLIST_HEAD(free);
|
||||
struct hlist_node *pos, *next;
|
||||
struct rpc_cred *cred;
|
||||
|
@ -157,6 +156,21 @@ rpcauth_free_credcache(struct rpc_auth *auth)
|
|||
rpcauth_destroy_credlist(&free);
|
||||
}
|
||||
|
||||
/*
|
||||
* Destroy the RPC credential cache
|
||||
*/
|
||||
void
|
||||
rpcauth_destroy_credcache(struct rpc_auth *auth)
|
||||
{
|
||||
struct rpc_cred_cache *cache = auth->au_credcache;
|
||||
|
||||
if (cache) {
|
||||
auth->au_credcache = NULL;
|
||||
rpcauth_clear_credcache(cache);
|
||||
kfree(cache);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
rpcauth_prune_expired(struct rpc_auth *auth, struct rpc_cred *cred, struct hlist_head *free)
|
||||
{
|
||||
|
|
|
@ -665,12 +665,13 @@ gss_destroy(struct rpc_auth *auth)
|
|||
dprintk("RPC: destroying GSS authenticator %p flavor %d\n",
|
||||
auth, auth->au_flavor);
|
||||
|
||||
rpcauth_destroy_credcache(auth);
|
||||
|
||||
gss_auth = container_of(auth, struct gss_auth, rpc_auth);
|
||||
rpc_unlink(gss_auth->dentry);
|
||||
gss_auth->dentry = NULL;
|
||||
gss_mech_put(gss_auth->mech);
|
||||
|
||||
rpcauth_free_credcache(auth);
|
||||
kfree(gss_auth);
|
||||
module_put(THIS_MODULE);
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@ static void
|
|||
unx_destroy(struct rpc_auth *auth)
|
||||
{
|
||||
dprintk("RPC: destroying UNIX authenticator %p\n", auth);
|
||||
rpcauth_free_credcache(auth);
|
||||
rpcauth_clear_credcache(auth->au_credcache);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -57,7 +57,7 @@ EXPORT_SYMBOL(rpcauth_unregister);
|
|||
EXPORT_SYMBOL(rpcauth_create);
|
||||
EXPORT_SYMBOL(rpcauth_lookupcred);
|
||||
EXPORT_SYMBOL(rpcauth_lookup_credcache);
|
||||
EXPORT_SYMBOL(rpcauth_free_credcache);
|
||||
EXPORT_SYMBOL(rpcauth_destroy_credcache);
|
||||
EXPORT_SYMBOL(rpcauth_init_credcache);
|
||||
EXPORT_SYMBOL(put_rpccred);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче