For one same connection, tipc_close_conn() and tipc_conn_sendmsg()
might be conducted on different cores in parallel. Once connection
is flagged as close, we should not queue swork item to workqueue.

But as sk->sk_callback_lock is not taken in tipc_conn_sendmsg(), a
swork item might be queued into s->send_wq workqueue even if the
connection has been shut down in tipc_close_conn() on another core.

To prevent the race condition from happening, we first hold
sk->sk_callback and then ensure connection flags and sk->sk_user_data
are both valid before swork item is queued into s->send_wq workqueue.

Signed-off-by: Ying Xue <[email protected]>
---
 net/tipc/server.c | 17 +++++++++++------
 1 file changed, 11 insertions(+), 6 deletions(-)

diff --git a/net/tipc/server.c b/net/tipc/server.c
index acaef80..571e137 100644
--- a/net/tipc/server.c
+++ b/net/tipc/server.c
@@ -449,16 +449,12 @@ int tipc_conn_sendmsg(struct tipc_server *s, int conid,
 {
        struct outqueue_entry *e;
        struct tipc_conn *con;
+       struct sock *sk;
 
        con = tipc_conn_lookup(s, conid);
        if (!con)
                return -EINVAL;
 
-       if (!test_bit(CF_CONNECTED, &con->flags)) {
-               conn_put(con);
-               return 0;
-       }
-
        e = tipc_alloc_entry(data, len);
        if (!e) {
                conn_put(con);
@@ -472,8 +468,17 @@ int tipc_conn_sendmsg(struct tipc_server *s, int conid,
        list_add_tail(&e->list, &con->outqueue);
        spin_unlock_bh(&con->outqueue_lock);
 
-       if (!queue_work(s->send_wq, &con->swork))
+       sk = con->sock->sk;
+
+       read_lock_bh(&sk->sk_callback_lock);
+       if (sk->sk_user_data && test_bit(CF_CONNECTED, &con->flags)) {
+               if (!queue_work(s->send_wq, &con->swork))
+                       conn_put(con);
+       } else {
                conn_put(con);
+       }
+       read_unlock_bh(&sk->sk_callback_lock);
+
        return 0;
 }
 
-- 
2.7.4


------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
tipc-discussion mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/tipc-discussion

Reply via email to