diff options
author | Alexey Kodanev <alexey.kodanev@oracle.com> | 2018-01-26 15:14:16 +0300 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2018-01-31 14:03:44 +0100 |
commit | c277f3420a638d455162a8bfccb40ebe22ba57b4 (patch) | |
tree | 6e94340f96413f60569bcc4e0f05e499aba98b3f /net/dccp | |
parent | 42d68bf2a42381642ea5ae460c6a5d86a56213f0 (diff) | |
download | linux-exynos-c277f3420a638d455162a8bfccb40ebe22ba57b4.tar.gz linux-exynos-c277f3420a638d455162a8bfccb40ebe22ba57b4.tar.bz2 linux-exynos-c277f3420a638d455162a8bfccb40ebe22ba57b4.zip |
dccp: don't restart ccid2_hc_tx_rto_expire() if sk in closed state
[ Upstream commit dd5684ecae3bd8e44b644f50e2c12c7e57fdfef5 ]
ccid2_hc_tx_rto_expire() timer callback always restarts the timer
again and can run indefinitely (unless it is stopped outside), and after
commit 120e9dabaf55 ("dccp: defer ccid_hc_tx_delete() at dismantle time"),
which moved ccid_hc_tx_delete() (also includes sk_stop_timer()) from
dccp_destroy_sock() to sk_destruct(), this started to happen quite often.
The timer prevents releasing the socket, as a result, sk_destruct() won't
be called.
Found with LTP/dccp_ipsec tests running on the bonding device,
which later couldn't be unloaded after the tests were completed:
unregister_netdevice: waiting for bond0 to become free. Usage count = 148
Fixes: 2a91aa396739 ("[DCCP] CCID2: Initial CCID2 (TCP-Like) implementation")
Signed-off-by: Alexey Kodanev <alexey.kodanev@oracle.com>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'net/dccp')
-rw-r--r-- | net/dccp/ccids/ccid2.c | 3 |
1 files changed, 3 insertions, 0 deletions
diff --git a/net/dccp/ccids/ccid2.c b/net/dccp/ccids/ccid2.c index e1295d5f2c56..97791b0b1b51 100644 --- a/net/dccp/ccids/ccid2.c +++ b/net/dccp/ccids/ccid2.c @@ -140,6 +140,9 @@ static void ccid2_hc_tx_rto_expire(unsigned long data) ccid2_pr_debug("RTO_EXPIRE\n"); + if (sk->sk_state == DCCP_CLOSED) + goto out; + /* back-off timer */ hc->tx_rto <<= 1; if (hc->tx_rto > DCCP_RTO_MAX) |