diff options
author | Frank Filz <ffilzlnx@us.ibm.com> | 2007-05-09 05:34:53 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-05-09 15:30:54 -0400 |
commit | 54f9247b3f6e51b24a4b7e873b3ab34d8e59dc45 (patch) | |
tree | 30954f9f05e622798e11a368a487d6cb7e87e132 | |
parent | 153e44d22fb5f98198f90fbf56e89b345e48534d (diff) |
knfsd: fix resource leak resulting in module refcount leak for rpcsec_gss_krb5.ko
I have been investigating a module reference count leak on the server for
rpcsec_gss_krb5.ko. It turns out the problem is a reference count leak for
the security context in net/sunrpc/auth_gss/svcauth_gss.c.
The problem is that gss_write_init_verf() calls gss_svc_searchbyctx() which
does a rsc_lookup() but never releases the reference to the context. There is
another issue that rpc.svcgssd sets an "end of time" expiration for the
context
By adding a cache_put() call in gss_svc_searchbyctx(), and setting an
expiration timeout in the downcall, cache_clean() does clean up the context
and the module reference count now goes to zero after unmount.
I also verified that if the context expires and then the client makes a new
request, a new context is established.
Here is the patch to fix the kernel, I will start a separate thread to discuss
what expiration time should be set by rpc.svcgssd.
Acked-by: "J. Bruce Fields" <bfields@citi.umich.edu>
Signed-off-by: Frank Filz <ffilzlnx@us.ibm.com>
Signed-off-by: Neil Brown <neilb@suse.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | net/sunrpc/auth_gss/svcauth_gss.c | 5 |
1 files changed, 4 insertions, 1 deletions
diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c index c678f5f461c6..9c0508e5493d 100644 --- a/net/sunrpc/auth_gss/svcauth_gss.c +++ b/net/sunrpc/auth_gss/svcauth_gss.c | |||
@@ -924,6 +924,7 @@ static inline int | |||
924 | gss_write_init_verf(struct svc_rqst *rqstp, struct rsi *rsip) | 924 | gss_write_init_verf(struct svc_rqst *rqstp, struct rsi *rsip) |
925 | { | 925 | { |
926 | struct rsc *rsci; | 926 | struct rsc *rsci; |
927 | int rc; | ||
927 | 928 | ||
928 | if (rsip->major_status != GSS_S_COMPLETE) | 929 | if (rsip->major_status != GSS_S_COMPLETE) |
929 | return gss_write_null_verf(rqstp); | 930 | return gss_write_null_verf(rqstp); |
@@ -932,7 +933,9 @@ gss_write_init_verf(struct svc_rqst *rqstp, struct rsi *rsip) | |||
932 | rsip->major_status = GSS_S_NO_CONTEXT; | 933 | rsip->major_status = GSS_S_NO_CONTEXT; |
933 | return gss_write_null_verf(rqstp); | 934 | return gss_write_null_verf(rqstp); |
934 | } | 935 | } |
935 | return gss_write_verf(rqstp, rsci->mechctx, GSS_SEQ_WIN); | 936 | rc = gss_write_verf(rqstp, rsci->mechctx, GSS_SEQ_WIN); |
937 | cache_put(&rsci->h, &rsc_cache); | ||
938 | return rc; | ||
936 | } | 939 | } |
937 | 940 | ||
938 | /* | 941 | /* |