diff options
author | J. Bruce Fields <bfields@redhat.com> | 2011-03-08 04:50:47 +0100 |
---|---|---|
committer | J. Bruce Fields <bfields@redhat.com> | 2011-03-08 17:51:29 +0100 |
commit | 8b3e07ac908d005bb791410f594cce8744f6806a (patch) | |
tree | 8b1d3cf7295110738dc8a59e3f44f443ded97859 | |
parent | nfsd41: modify the members value of nfsd4_op_flags (diff) | |
download | linux-8b3e07ac908d005bb791410f594cce8744f6806a.tar.xz linux-8b3e07ac908d005bb791410f594cce8744f6806a.zip |
svcrpc: fix rare race on unix_domain creation
Note that "new" here is not yet fully initialized; auth_domain_put
should be called only on auth_domains that have actually been added to
the hash.
Before this fix, two attempts to add the same domain at once could
cause the hlist_del in auth_domain_put to fail.
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
-rw-r--r-- | net/sunrpc/svcauth_unix.c | 18 |
1 files changed, 9 insertions, 9 deletions
diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c index 30916b06c12b..d100bf2b4e81 100644 --- a/net/sunrpc/svcauth_unix.c +++ b/net/sunrpc/svcauth_unix.c @@ -38,6 +38,14 @@ struct unix_domain { extern struct auth_ops svcauth_unix; +static void svcauth_unix_domain_release(struct auth_domain *dom) +{ + struct unix_domain *ud = container_of(dom, struct unix_domain, h); + + kfree(dom->name); + kfree(ud); +} + struct auth_domain *unix_domain_find(char *name) { struct auth_domain *rv; @@ -47,7 +55,7 @@ struct auth_domain *unix_domain_find(char *name) while(1) { if (rv) { if (new && rv != &new->h) - auth_domain_put(&new->h); + svcauth_unix_domain_release(new); if (rv->flavour != &svcauth_unix) { auth_domain_put(rv); @@ -74,14 +82,6 @@ struct auth_domain *unix_domain_find(char *name) } EXPORT_SYMBOL_GPL(unix_domain_find); -static void svcauth_unix_domain_release(struct auth_domain *dom) -{ - struct unix_domain *ud = container_of(dom, struct unix_domain, h); - - kfree(dom->name); - kfree(ud); -} - /************************************************** * cache for IP address to unix_domain |