linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] SUNRPC: Fix refcnt leak in rpc_clnt_test_and_add_xprt
@ 2020-04-20  5:45 Xiyu Yang
  2020-04-20 11:54 ` Trond Myklebust
  0 siblings, 1 reply; 2+ messages in thread
From: Xiyu Yang @ 2020-04-20  5:45 UTC (permalink / raw)
  To: J. Bruce Fields, Chuck Lever, Trond Myklebust, Anna Schumaker,
	David S. Miller, Jakub Kicinski, linux-nfs, netdev, linux-kernel
  Cc: yuanxzhang, kjlu, Xiyu Yang, Xin Tan

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@fudan.edu.cn>
Signed-off-by: Xin Tan <tanxin.ctf@gmail.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


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH] SUNRPC: Fix refcnt leak in rpc_clnt_test_and_add_xprt
  2020-04-20  5:45 [PATCH] SUNRPC: Fix refcnt leak in rpc_clnt_test_and_add_xprt Xiyu Yang
@ 2020-04-20 11:54 ` Trond Myklebust
  0 siblings, 0 replies; 2+ messages in thread
From: Trond Myklebust @ 2020-04-20 11:54 UTC (permalink / raw)
  To: xiyuyang19, davem, chuck.lever, linux-kernel, netdev, kuba,
	bfields, linux-nfs, anna.schumaker
  Cc: tanxin.ctf, yuanxzhang, kjlu

On Mon, 2020-04-20 at 13:45 +0800, Xiyu Yang wrote:
> 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@fudan.edu.cn>
> Signed-off-by: Xin Tan <tanxin.ctf@gmail.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);

We should just get rid of the IS_ERR() condition here. It cannot ever
trigger, which is why rpc_run_task() no longer checks for it, and no
longer calls the ->rpc_release() method on error.

> +	}
>  	rpc_put_task(task);
>  success:
>  	return 1;
-- 
Trond Myklebust
Linux NFS client maintainer, Hammerspace
trond.myklebust@hammerspace.com



^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2020-04-20 11:54 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-04-20  5:45 [PATCH] SUNRPC: Fix refcnt leak in rpc_clnt_test_and_add_xprt Xiyu Yang
2020-04-20 11:54 ` Trond Myklebust

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).