Blob Blame History Raw
From: NeilBrown <neilb@suse.com>
Subject: [kabi fix for] SUNRPC: Do not dereference non-socket transports in sysfs
Patch-mainline: Never, kabi
References: git-fixes

Move new rpc_xprt_ops fields to end of structure, and hide from kabi.
Only access them after checking the ops structure is known to have the fields.
Restore get_srcport()

Signed-off-by: NeilBrown <neilb@suse.de>

---
 include/linux/sunrpc/xprt.h |    8 +++++---
 net/sunrpc/sysfs.c          |    4 +++-
 net/sunrpc/xprtsock.c       |    6 ++++++
 3 files changed, 14 insertions(+), 4 deletions(-)

--- a/include/linux/sunrpc/xprt.h
+++ b/include/linux/sunrpc/xprt.h
@@ -139,9 +139,6 @@ struct rpc_xprt_ops {
 	void		(*rpcbind)(struct rpc_task *task);
 	void		(*set_port)(struct rpc_xprt *xprt, unsigned short port);
 	void		(*connect)(struct rpc_xprt *xprt, struct rpc_task *task);
-	int		(*get_srcaddr)(struct rpc_xprt *xprt, char *buf,
-				       size_t buflen);
-	unsigned short	(*get_srcport)(struct rpc_xprt *xprt);
 	int		(*buf_alloc)(struct rpc_task *task);
 	void		(*buf_free)(struct rpc_task *task);
 	void		(*prepare_request)(struct rpc_rqst *req);
@@ -165,6 +162,11 @@ struct rpc_xprt_ops {
 	void		(*bc_free_rqst)(struct rpc_rqst *rqst);
 	void		(*bc_destroy)(struct rpc_xprt *xprt,
 				      unsigned int max_reqs);
+#ifndef __GENKSYMS__
+	int		(*get_srcaddr)(struct rpc_xprt *xprt, char *buf,
+				       size_t buflen);
+	unsigned short	(*get_srcport)(struct rpc_xprt *xprt);
+#endif
 };
 
 /*
--- a/net/sunrpc/sysfs.c
+++ b/net/sunrpc/sysfs.c
@@ -113,7 +113,9 @@ static ssize_t rpc_sysfs_xprt_info_show(
 		return -ENOTCONN;
 	}
 
-	if (xprt->ops->get_srcport)
+	if ((xprt->xprt_class->ident == XPRT_TRANSPORT_TCP ||
+	     xprt->xprt_class->ident == XPRT_TRANSPORT_TCP) &&
+	    xprt->ops->get_srcport)
 		srcport = xprt->ops->get_srcport(xprt);
 
 	ret = snprintf(buf, buflen,
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -1664,6 +1664,12 @@ static unsigned short xs_sock_srcport(st
 	return ret;
 }
 
+unsigned short get_srcport(struct rpc_xprt *xprt)
+{
+	return xs_sock_srcport(xprt);
+}
+EXPORT_SYMBOL(get_srcport);
+
 static int xs_sock_srcaddr(struct rpc_xprt *xprt, char *buf, size_t buflen)
 {
 	struct sock_xprt *sock = container_of(xprt, struct sock_xprt, xprt);