[PATCH 1/2] SUNRPC: Do not dereference non-socket transports in sysfs

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Trond Myklebust <trond.myklebust@xxxxxxxxxxxxxxx>

Do not cast the struct xprt to a sock_xprt unless we know it is a UDP or
TCP transport. Otherwise the call to lock the mutex will scribble over
whatever structure is actually there. This has been seen to cause hard
system lockups when the underlying transport was RDMA.

Fixes: e44773daf851 ("SUNRPC: Add srcaddr as a file in sysfs")
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Trond Myklebust <trond.myklebust@xxxxxxxxxxxxxxx>
---
 net/sunrpc/sysfs.c | 32 ++++++++++++++++++++++----------
 1 file changed, 22 insertions(+), 10 deletions(-)

diff --git a/net/sunrpc/sysfs.c b/net/sunrpc/sysfs.c
index 05c758da6a92..8ce053f84421 100644
--- a/net/sunrpc/sysfs.c
+++ b/net/sunrpc/sysfs.c
@@ -107,22 +107,34 @@ static ssize_t rpc_sysfs_xprt_srcaddr_show(struct kobject *kobj,
 	struct rpc_xprt *xprt = rpc_sysfs_xprt_kobj_get_xprt(kobj);
 	struct sockaddr_storage saddr;
 	struct sock_xprt *sock;
+	const char *fmt = "<closed>\n";
 	ssize_t ret = -1;
 
-	if (!xprt || !xprt_connected(xprt)) {
-		xprt_put(xprt);
-		return -ENOTCONN;
-	}
+	if (!xprt || !xprt_connected(xprt))
+		goto out;
 
-	sock = container_of(xprt, struct sock_xprt, xprt);
-	mutex_lock(&sock->recv_mutex);
-	if (sock->sock == NULL ||
-	    kernel_getsockname(sock->sock, (struct sockaddr *)&saddr) < 0)
+	switch (xprt->xprt_class->ident) {
+	case XPRT_TRANSPORT_UDP:
+	case XPRT_TRANSPORT_TCP:
+		break;
+	default:
+		fmt = "<not a socket>\n";
 		goto out;
+	};
 
-	ret = sprintf(buf, "%pISc\n", &saddr);
-out:
+	sock = container_of(xprt, struct sock_xprt, xprt);
+	mutex_lock(&sock->recv_mutex);
+	if (sock->sock != NULL) {
+		ret = kernel_getsockname(sock->sock, (struct sockaddr *)&saddr);
+		if (ret >= 0) {
+			ret = sprintf(buf, "%pISc\n", &saddr);
+			fmt = NULL;
+		}
+	}
 	mutex_unlock(&sock->recv_mutex);
+out:
+	if (fmt)
+		ret = sprintf(buf, fmt);
 	xprt_put(xprt);
 	return ret + 1;
 }
-- 
2.35.1




[Index of Archives]     [Linux Filesystem Development]     [Linux USB Development]     [Linux Media Development]     [Video for Linux]     [Linux NILFS]     [Linux Audio Users]     [Yosemite Info]     [Linux SCSI]

  Powered by Linux