[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <1587361519-83687-1-git-send-email-xiyuyang19@fudan.edu.cn>
Date: Mon, 20 Apr 2020 13:45:19 +0800
From: Xiyu Yang <xiyuyang19@...an.edu.cn>
To: "J. Bruce Fields" <bfields@...ldses.org>,
Chuck Lever <chuck.lever@...cle.com>,
Trond Myklebust <trond.myklebust@...merspace.com>,
Anna Schumaker <anna.schumaker@...app.com>,
"David S. Miller" <davem@...emloft.net>,
Jakub Kicinski <kuba@...nel.org>, linux-nfs@...r.kernel.org,
netdev@...r.kernel.org, linux-kernel@...r.kernel.org
Cc: yuanxzhang@...an.edu.cn, kjlu@....edu,
Xiyu Yang <xiyuyang19@...an.edu.cn>,
Xin Tan <tanxin.ctf@...il.com>
Subject: [PATCH] SUNRPC: Fix refcnt leak in rpc_clnt_test_and_add_xprt
rpc_clnt_test_and_add_xprt() invokes xprt_switch_get() and xprt_get(),
which returns a reference of the rpc_xprt_switch object to "data->xps"
and a reference of the rpc_xprt object to "data->xprt" with increased
refcount.
When rpc_clnt_test_and_add_xprt() returns, local variable "data" and its
field "xps" as well as "xprt" becomes invalid, so their refcounts should
be decreased to keep refcount balanced.
The reference counting issue happens in one exception handling paths of
rpc_clnt_test_and_add_xprt(). When rpc_call_null_helper() returns
IS_ERR, the refcnt increased by xprt_switch_get() and xprt_get() are not
decreased, causing a refcnt leak.
Fix this issue by calling rpc_cb_add_xprt_release() to decrease related
refcounted fields in "data" and then release it when
rpc_call_null_helper() returns IS_ERR.
Fixes: 7f554890587c ("SUNRPC: Allow addition of new transports to a
struct rpc_clnt")
Signed-off-by: Xiyu Yang <xiyuyang19@...an.edu.cn>
Signed-off-by: Xin Tan <tanxin.ctf@...il.com>
---
net/sunrpc/clnt.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index 7324b21f923e..f86d9ae2167f 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -2803,8 +2803,10 @@ int rpc_clnt_test_and_add_xprt(struct rpc_clnt *clnt,
task = rpc_call_null_helper(clnt, xprt, NULL,
RPC_TASK_SOFT|RPC_TASK_SOFTCONN|RPC_TASK_ASYNC|RPC_TASK_NULLCREDS,
&rpc_cb_add_xprt_call_ops, data);
- if (IS_ERR(task))
+ if (IS_ERR(task)) {
+ rpc_cb_add_xprt_release(data);
return PTR_ERR(task);
+ }
rpc_put_task(task);
success:
return 1;
--
2.7.4
Powered by blists - more mailing lists