Patch "tipc: fix connection refcount error" has been added to the 4.9-stable tree
Subsystems (3)
This is a note to let you know that I've just added the patch titled
tipc: fix connection refcount error
to the 4.9-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
tipc-fix-connection-refcount-error.patch
and it can be found in the queue-4.9 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From foo@baz Thu Jun 15 16:35:05 CEST 2017
From: Parthasarathy Bhuvaragan <[email protected]>
Date: Tue, 24 Jan 2017 13:00:45 +0100
Subject: tipc: fix connection refcount error
From: Parthasarathy Bhuvaragan <[email protected]>
[ Upstream commit fc0adfc8fd18b61b6f7a3f28b429e134d6f3a008 ]
Until now, the generic server framework maintains the connection id's per subscriber in server's conn_idr. At tipc_close_conn, we remove the connection id from the server list, but the connection is valid until we call the refcount cleanup. Hence we have a window where the server allocates the same connection to an new subscriber leading to inconsistent reference count. We have another refcount warning we grab the refcount in tipc_conn_lookup() for connections with flag with CF_CONNECTED not set. This usually occurs at shutdown when the we stop the topology server and withdraw TIPC_CFG_SRV publication thereby triggering a withdraw message to subscribers.
In this commit, we:
1. remove the connection from the server list at recount cleanup.
2. grab the refcount for a connection only if CF_CONNECTED is set.
--- net/tipc/server.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-)
net/tipc/server.c +10 -9
@@ -91,7 +91,8 @@ static void tipc_sock_release(struct tipstatic void tipc_conn_kref_release (struct kref *kref) { struct tipc_conn *con = container_of(kref, struct tipc_conn, kref); -struct sockaddr_tipc *saddr = con->server->saddr; +struct tipc_server *s = con->server; +struct sockaddr_tipc *saddr = s->saddr;struct socket *sock = con->sock;struct sock *sk;
@@ -106,6 +107,11 @@ static void tipc_conn_kref_release(structipc_sock_release (con);sock_release (sock); con->sock =NULL ; + +spin_lock_bh (&s->idr_lock); +idr_remove (&s->conn_idr, con->conid); + s->idr_in_use--; +spin_unlock_bh (&s->idr_lock); }tipc_clean_outqueues (con);
@@ -128,8 +134,10 @@ static struct tipc_conn *tipc_conn_lookuspin_lock_bh (&s->idr_lock); con =idr_find (&s->conn_idr, conid); -if (con) +if (con &&test_bit (CF_CONNECTED , &con->flags))conn_get (con); +else + con =NULL ;spin_unlock_bh (&s->idr_lock);return con; }
@@ -198,15 +206,8 @@ static void tipc_sock_release(struct tipstatic void tipc_close_conn (struct tipc_conn *con) { -struct tipc_server *s = con->server; -if (test_and_clear_bit (CF_CONNECTED , &con->flags)) { -spin_lock_bh (&s->idr_lock); -idr_remove (&s->conn_idr, con->conid); - s->idr_in_use--; -spin_unlock_bh (&s->idr_lock); -/* We shouldn't flush pending works as we may be in the * thread. In fact the races with pending rx/tx work structs * are harmless for us here as we have already deleted this
Patches currently in stable-queue which might be from [email protected] are
queue-4.9/tipc-fix-connection-refcount-error.patch queue-4.9/tipc-fix-nametbl_lock-soft-lockup-at-node-link-events.patch queue-4.9/tipc-ignore-requests-when-the-connection-state-is-not-connected.patch queue-4.9/tipc-add-subscription-refcount-to-avoid-invalid-delete.patch