]> git.karo-electronics.de Git - linux-beck.git/commitdiff
sunrpc: svc_sock_names should hold ref to socket being closed.
authorNeilBrown <neilb@suse.de>
Mon, 15 Nov 2010 00:27:01 +0000 (11:27 +1100)
committerJ. Bruce Fields <bfields@redhat.com>
Fri, 17 Dec 2010 20:48:19 +0000 (15:48 -0500)
Currently svc_sock_names calls svc_close_xprt on a svc_sock to
which it does not own a reference.
As soon as svc_close_xprt sets XPT_CLOSE, the socket could be
freed by a separate thread (though this is a very unlikely race).

It is safer to hold a reference while calling svc_close_xprt.

Signed-off-by: NeilBrown <neilb@suse.de>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
net/sunrpc/svcsock.c

index 07919e16be3ef3a274d7c099c2e58d2884067edf..52bd1130e83a15ebbc60ee78b41069dc87c5d25e 100644 (file)
@@ -324,19 +324,21 @@ int svc_sock_names(struct svc_serv *serv, char *buf, const size_t buflen,
                        len = onelen;
                        break;
                }
-               if (toclose && strcmp(toclose, buf + len) == 0)
+               if (toclose && strcmp(toclose, buf + len) == 0) {
                        closesk = svsk;
-               else
+                       svc_xprt_get(&closesk->sk_xprt);
+               } else
                        len += onelen;
        }
        spin_unlock_bh(&serv->sv_lock);
 
-       if (closesk)
+       if (closesk) {
                /* Should unregister with portmap, but you cannot
                 * unregister just one protocol...
                 */
                svc_close_xprt(&closesk->sk_xprt);
-       else if (toclose)
+               svc_xprt_put(&closesk->sk_xprt);
+       } else if (toclose)
                return -ENOENT;
        return len;
 }