Re: [tipc-discussion] [net 1/2] tipc: fix memory leak in service subscripting

2020-05-11 Thread Ying Xue
Good catch!

On 5/7/20 7:12 PM, Tuong Lien wrote:
> Upon receipt of a service subscription request from user via a topology
> connection, one 'sub' object will be allocated in kernel, so it will be
> able to send an event of the service if any to the user correspondingly
> then. Also, in case of any failure, the connection will be shutdown and
> all the pertaining 'sub' objects will be freed.
> 
> However, there is a race condition as follows resulting in memory leak:
> 
>receive-work   connectionsend-work
>   |||
> sub-1 |<--//---||
> sub-2 |<--//---||
>   ||<---| evt for sub-x
> sub-3 |<--//---||
>   :::
>   :::
>   |   /||
>   |   |* peer closed|
>   |   |||
>   |   ||<---X---| evt for sub-y
>   |   ||<===|
> sub-n |<--/Xshutdown|
> -> orphan | |
> 
> That is, the 'receive-work' may get the last subscription request while
> the 'send-work' is shutting down the connection due to peer close.
> 
> We had a 'lock' on the connection, so the two actions cannot be carried
> out simultaneously. If the last subscription is allocated e.g. 'sub-n',
> before the 'send-work' closes the connection, there will be no issue at
> all, the 'sub' objects will be freed. In contrast the last subscription
> will become orphan since the connection was closed, and we released all
> references.
> 
> This commit fixes the issue by simply adding one test if the connection
> remains in 'connected' state soon after we obtain the connection's lock
> then a subscription object can be created as usual, otherwise we ignore
> it.
> 
> Reported-by: Thang Ngo 
> Signed-off-by: Tuong Lien 

Acked-by: Ying Xue 

> ---
>  net/tipc/topsrv.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/net/tipc/topsrv.c b/net/tipc/topsrv.c
> index 73dbed0c4b6b..399a89f6f1bf 100644
> --- a/net/tipc/topsrv.c
> +++ b/net/tipc/topsrv.c
> @@ -400,7 +400,9 @@ static int tipc_conn_rcv_from_sock(struct tipc_conn *con)
>   return -EWOULDBLOCK;
>   if (ret == sizeof(s)) {
>   read_lock_bh(>sk_callback_lock);
> - ret = tipc_conn_rcv_sub(srv, con, );
> + /* RACE: the connection can be closed in meanwhile */
> + if (likely(connected(con)))
> + ret = tipc_conn_rcv_sub(srv, con, );
>   read_unlock_bh(>sk_callback_lock);
>   if (!ret)
>   return 0;
> 


___
tipc-discussion mailing list
tipc-discussion@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/tipc-discussion


Re: [tipc-discussion] [net 1/2] tipc: fix memory leak in service subscripting

2020-05-07 Thread Jon Maloy




On 5/7/20 7:12 AM, Tuong Lien wrote:

Upon receipt of a service subscription request from user via a topology
connection, one 'sub' object will be allocated in kernel, so it will be
able to send an event of the service if any to the user correspondingly
then. Also, in case of any failure, the connection will be shutdown and
all the pertaining 'sub' objects will be freed.

However, there is a race condition as follows resulting in memory leak:

receive-work   connectionsend-work
   |||
 sub-1 |<--//---||
 sub-2 |<--//---||
   ||<---| evt for sub-x
 sub-3 |<--//---||
   :::
   :::
   |   /||
   |   |* peer closed|
   |   |||
   |   ||<---X---| evt for sub-y
   |   ||<===|
 sub-n |<--/Xshutdown|
 -> orphan | |

That is, the 'receive-work' may get the last subscription request while
the 'send-work' is shutting down the connection due to peer close.

We had a 'lock' on the connection, so the two actions cannot be carried
out simultaneously. If the last subscription is allocated e.g. 'sub-n',
before the 'send-work' closes the connection, there will be no issue at
all, the 'sub' objects will be freed. In contrast the last subscription
will become orphan since the connection was closed, and we released all
references.

This commit fixes the issue by simply adding one test if the connection
remains in 'connected' state soon after we obtain the connection's lock
then a subscription object can be created as usual, otherwise we ignore
it.

Reported-by: Thang Ngo 
Signed-off-by: Tuong Lien 
---
  net/tipc/topsrv.c | 4 +++-
  1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/net/tipc/topsrv.c b/net/tipc/topsrv.c
index 73dbed0c4b6b..399a89f6f1bf 100644
--- a/net/tipc/topsrv.c
+++ b/net/tipc/topsrv.c
@@ -400,7 +400,9 @@ static int tipc_conn_rcv_from_sock(struct tipc_conn *con)
return -EWOULDBLOCK;
if (ret == sizeof(s)) {
read_lock_bh(>sk_callback_lock);
-   ret = tipc_conn_rcv_sub(srv, con, );
+   /* RACE: the connection can be closed in meanwhile */

s/in meanwhile/in the meantime/

+   if (likely(connected(con)))
+   ret = tipc_conn_rcv_sub(srv, con, );
read_unlock_bh(>sk_callback_lock);
if (!ret)
return 0;

Acked-by: Jon Maloy 



___
tipc-discussion mailing list
tipc-discussion@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/tipc-discussion


[tipc-discussion] [net 1/2] tipc: fix memory leak in service subscripting

2020-05-07 Thread Tuong Lien
Upon receipt of a service subscription request from user via a topology
connection, one 'sub' object will be allocated in kernel, so it will be
able to send an event of the service if any to the user correspondingly
then. Also, in case of any failure, the connection will be shutdown and
all the pertaining 'sub' objects will be freed.

However, there is a race condition as follows resulting in memory leak:

   receive-work   connectionsend-work
  |||
sub-1 |<--//---||
sub-2 |<--//---||
  ||<---| evt for sub-x
sub-3 |<--//---||
  :::
  :::
  |   /||
  |   |* peer closed|
  |   |||
  |   ||<---X---| evt for sub-y
  |   ||<===|
sub-n |<--/Xshutdown|
-> orphan | |

That is, the 'receive-work' may get the last subscription request while
the 'send-work' is shutting down the connection due to peer close.

We had a 'lock' on the connection, so the two actions cannot be carried
out simultaneously. If the last subscription is allocated e.g. 'sub-n',
before the 'send-work' closes the connection, there will be no issue at
all, the 'sub' objects will be freed. In contrast the last subscription
will become orphan since the connection was closed, and we released all
references.

This commit fixes the issue by simply adding one test if the connection
remains in 'connected' state soon after we obtain the connection's lock
then a subscription object can be created as usual, otherwise we ignore
it.

Reported-by: Thang Ngo 
Signed-off-by: Tuong Lien 
---
 net/tipc/topsrv.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/net/tipc/topsrv.c b/net/tipc/topsrv.c
index 73dbed0c4b6b..399a89f6f1bf 100644
--- a/net/tipc/topsrv.c
+++ b/net/tipc/topsrv.c
@@ -400,7 +400,9 @@ static int tipc_conn_rcv_from_sock(struct tipc_conn *con)
return -EWOULDBLOCK;
if (ret == sizeof(s)) {
read_lock_bh(>sk_callback_lock);
-   ret = tipc_conn_rcv_sub(srv, con, );
+   /* RACE: the connection can be closed in meanwhile */
+   if (likely(connected(con)))
+   ret = tipc_conn_rcv_sub(srv, con, );
read_unlock_bh(>sk_callback_lock);
if (!ret)
return 0;
-- 
2.13.7



___
tipc-discussion mailing list
tipc-discussion@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/tipc-discussion