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. Commit17f09d3f61
("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:17f09d3f61
("SUNRPC: Check if the xprt is connected before handling sysfs reads") Fixes:a8482488a7
("SUNRPC query transport's source port") Signed-off-by: NeilBrown <neilb@suse.de> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
This commit is contained in:
Родитель
63db37e99a
Коммит
b49ea673e1
|
@ -115,11 +115,14 @@ static ssize_t rpc_sysfs_xprt_srcaddr_show(struct kobject *kobj,
|
||||||
}
|
}
|
||||||
|
|
||||||
sock = container_of(xprt, struct sock_xprt, xprt);
|
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;
|
goto out;
|
||||||
|
|
||||||
ret = sprintf(buf, "%pISc\n", &saddr);
|
ret = sprintf(buf, "%pISc\n", &saddr);
|
||||||
out:
|
out:
|
||||||
|
mutex_unlock(&sock->recv_mutex);
|
||||||
xprt_put(xprt);
|
xprt_put(xprt);
|
||||||
return ret + 1;
|
return ret + 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1641,7 +1641,12 @@ static int xs_get_srcport(struct sock_xprt *transport)
|
||||||
unsigned short get_srcport(struct rpc_xprt *xprt)
|
unsigned short get_srcport(struct rpc_xprt *xprt)
|
||||||
{
|
{
|
||||||
struct sock_xprt *sock = container_of(xprt, struct sock_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);
|
EXPORT_SYMBOL(get_srcport);
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче