Commit b49ea673 authored by NeilBrown's avatar NeilBrown Committed by Anna Schumaker
Browse files

SUNRPC: lock against ->sock changing during sysfs read



->sock can be set to NULL asynchronously unless ->recv_mutex is held.
So it is important to hold that mutex.  Otherwise a sysfs read can
trigger an oops.
Commit 17f09d3f ("SUNRPC: Check if the xprt is connected before
handling sysfs reads") appears to attempt to fix this problem, but it
only narrows the race window.

Fixes: 17f09d3f ("SUNRPC: Check if the xprt is connected before handling sysfs reads")
Fixes: a8482488 ("SUNRPC query transport's source port")
Signed-off-by: default avatarNeilBrown <neilb@suse.de>
Signed-off-by: default avatarAnna Schumaker <Anna.Schumaker@Netapp.com>
parent 63db37e9
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -115,11 +115,14 @@ static ssize_t rpc_sysfs_xprt_srcaddr_show(struct kobject *kobj,
	}

	sock = container_of(xprt, struct sock_xprt, xprt);
	if (kernel_getsockname(sock->sock, (struct sockaddr *)&saddr) < 0)
	mutex_lock(&sock->recv_mutex);
	if (sock->sock == NULL ||
	    kernel_getsockname(sock->sock, (struct sockaddr *)&saddr) < 0)
		goto out;

	ret = sprintf(buf, "%pISc\n", &saddr);
out:
	mutex_unlock(&sock->recv_mutex);
	xprt_put(xprt);
	return ret + 1;
}
+6 −1
Original line number Diff line number Diff line
@@ -1641,7 +1641,12 @@ static int xs_get_srcport(struct sock_xprt *transport)
unsigned short get_srcport(struct rpc_xprt *xprt)
{
	struct sock_xprt *sock = container_of(xprt, struct sock_xprt, xprt);
	return xs_sock_getport(sock->sock);
	unsigned short ret = 0;
	mutex_lock(&sock->recv_mutex);
	if (sock->sock)
		ret = xs_sock_getport(sock->sock);
	mutex_unlock(&sock->recv_mutex);
	return ret;
}
EXPORT_SYMBOL(get_srcport);