summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJ. Bruce Fields <bfields@redhat.com>2011-03-07 22:50:47 -0500
committerJ. Bruce Fields <bfields@redhat.com>2011-03-08 11:51:29 -0500
commit8b3e07ac908d005bb791410f594cce8744f6806a (patch)
tree8b1d3cf7295110738dc8a59e3f44f443ded97859
parent5ece3cafbd88d4da5c734e1810c4a2e6474b57b2 (diff)
downloadlinux-8b3e07ac908d005bb791410f594cce8744f6806a.tar.bz2
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.c18
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