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);