linux/net/dccp
Eric Dumazet ed2e923945 tcp/dccp: fix timewait races in timer handling
When creating a timewait socket, we need to arm the timer before
allowing other cpus to find it. The signal allowing cpus to find
the socket is setting tw_refcnt to non zero value.

As we set tw_refcnt in __inet_twsk_hashdance(), we therefore need to
call inet_twsk_schedule() first.

This also means we need to remove tw_refcnt changes from
inet_twsk_schedule() and let the caller handle it.

Note that because we use mod_timer_pinned(), we have the guarantee
the timer wont expire before we set tw_refcnt as we run in BH context.

To make things more readable I introduced inet_twsk_reschedule() helper.

When rearming the timer, we can use mod_timer_pending() to make sure
we do not rearm a canceled timer.

Note: This bug can possibly trigger if packets of a flow can hit
multiple cpus. This does not normally happen, unless flow steering
is broken somehow. This explains this bug was spotted ~5 months after
its introduction.

A similar fix is needed for SYN_RECV sockets in reqsk_queue_hash_req(),
but will be provided in a separate patch for proper tracking.

Fixes: 789f558cfb ("tcp/dccp: get rid of central timewait timer")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reported-by: Ying Cai <ycai@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2015-09-21 16:32:29 -07:00
..
ccids dccp: re-enable debug macro 2014-02-16 23:45:00 -05:00
Kconfig net/dccp: remove depends on CONFIG_EXPERIMENTAL 2013-01-11 11:39:34 -08:00
Makefile dccp: Policy-based packet dequeueing infrastructure 2010-12-07 13:47:12 +01:00
ackvec.c dccp: drop null test before destroy functions 2015-09-15 16:49:43 -07:00
ackvec.h net: dccp: Remove extern from function prototypes 2013-10-19 19:12:11 -04:00
ccid.c dccp: drop null test before destroy functions 2015-09-15 16:49:43 -07:00
ccid.h net: dccp: Remove extern from function prototypes 2013-10-19 19:12:11 -04:00
dccp.h ipv4: dccp: handle ICMP messages on DCCP_NEW_SYN_RECV request sockets 2015-03-23 16:52:26 -04:00
diag.c sock_diag: specify info_size per inet protocol 2015-06-15 19:49:22 -07:00
feat.c dccp: kerneldoc warning fixes 2014-11-18 15:26:31 -05:00
feat.h net: dccp: Remove extern from function prototypes 2013-10-19 19:12:11 -04:00
input.c dccp: spelling s/reseting/resetting 2014-11-18 15:26:32 -05:00
ipv4.c inet: fix possible panic in reqsk_queue_unlink() 2015-04-24 11:39:15 -04:00
ipv6.c inet: fix possible panic in reqsk_queue_unlink() 2015-04-24 11:39:15 -04:00
ipv6.h inet: includes a sock_common in request_sock 2013-10-10 00:08:07 -04:00
minisocks.c tcp/dccp: fix timewait races in timer handling 2015-09-21 16:32:29 -07:00
options.c dccp: remove obsolete code 2014-01-04 20:18:49 -05:00
output.c ipv4: add a sock pointer to ip_queue_xmit() 2014-04-15 12:58:34 -04:00
probe.c net: Remove iocb argument from sendmsg and recvmsg 2015-03-02 13:06:31 -05:00
proto.c tcp: fix recv with flags MSG_WAITALL | MSG_PEEK 2015-07-27 01:06:53 -07:00
qpolicy.c dccp qpolicy: Parameter checking of cmsg qpolicy parameters 2010-12-07 13:47:12 +01:00
sysctl.c dccp: make the request_retries minimum is 1 2014-05-14 15:34:16 -04:00
timer.c inet: get rid of central tcp/dccp listener timer 2015-03-20 12:40:25 -04:00