summaryrefslogtreecommitdiffstats
path: root/net/ipv4/inet_hashtables.c
diff options
context:
space:
mode:
authorEric Dumazet <eric.dumazet@gmail.com>2009-12-04 04:47:42 +0100
committerDavid S. Miller <davem@davemloft.net>2009-12-09 05:17:51 +0100
commit3cdaedae635b17ce23c738ce7d364b442310cdec (patch)
treeaf07cdf6c31cca8d1a094bd104efa65e1e95e270 /net/ipv4/inet_hashtables.c
parenttcp: Fix a connect() race with timewait sockets (diff)
downloadlinux-3cdaedae635b17ce23c738ce7d364b442310cdec.tar.xz
linux-3cdaedae635b17ce23c738ce7d364b442310cdec.zip
tcp: Fix a connect() race with timewait sockets
When we find a timewait connection in __inet_hash_connect() and reuse it for a new connection request, we have a race window, releasing bind list lock and reacquiring it in __inet_twsk_kill() to remove timewait socket from list. Another thread might find the timewait socket we already chose, leading to list corruption and crashes. Fix is to remove timewait socket from bind list before releasing the bind lock. Note: This problem happens if sysctl_tcp_tw_reuse is set. Reported-by: kapil dakhane <kdakhane@gmail.com> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/inet_hashtables.c')
-rw-r--r--net/ipv4/inet_hashtables.c2
1 files changed, 2 insertions, 0 deletions
diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c
index c4201b7ece38..2b79377b468d 100644
--- a/net/ipv4/inet_hashtables.c
+++ b/net/ipv4/inet_hashtables.c
@@ -502,6 +502,8 @@ ok:
inet_sk(sk)->inet_sport = htons(port);
twrefcnt += hash(sk, tw);
}
+ if (tw)
+ twrefcnt += inet_twsk_bind_unhash(tw, hinfo);
spin_unlock(&head->lock);
if (tw) {