linux/net/rds
Sowmini Varadhan 9c79440e2c RDS: TCP: fix race windows in send-path quiescence by rds_tcp_accept_one()
The send path needs to be quiesced before resetting callbacks from
rds_tcp_accept_one(), and commit eb19284026 ("RDS:TCP: Synchronize
rds_tcp_accept_one with rds_send_xmit when resetting t_sock") achieves
this using the c_state and RDS_IN_XMIT bit following the pattern
used by rds_conn_shutdown(). However this leaves the possibility
of a race window as shown in the sequence below
    take t_conn_lock in rds_tcp_conn_connect
    send outgoing syn to peer
    drop t_conn_lock in rds_tcp_conn_connect
    incoming from peer triggers rds_tcp_accept_one, conn is
	marked CONNECTING
    wait for RDS_IN_XMIT to quiesce any rds_send_xmit threads
    call rds_tcp_reset_callbacks
    [.. race-window where incoming syn-ack can cause the conn
	to be marked UP from rds_tcp_state_change ..]
    lock_sock called from rds_tcp_reset_callbacks, and we set
	t_sock to null
As soon as the conn is marked UP in the race-window above, rds_send_xmit()
threads will proceed to rds_tcp_xmit and may encounter a null-pointer
deref on the t_sock.

Given that rds_tcp_state_change() is invoked in softirq context, whereas
rds_tcp_reset_callbacks() is in workq context, and testing for RDS_IN_XMIT
after lock_sock could result in a deadlock with tcp_sendmsg, this
commit fixes the race by using a new c_state, RDS_TCP_RESETTING, which
will prevent a transition to RDS_CONN_UP from rds_tcp_state_change().

Signed-off-by: Sowmini Varadhan <sowmini.varadhan@oracle.com>
Acked-by: Santosh Shilimkar <santosh.shilimkar@oracle.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2016-06-07 15:10:15 -07:00
..
af_rds.c
bind.c
cong.c
connection.c
ib_cm.c
ib_fmr.c
ib_frmr.c
ib_mr.h
ib_rdma.c
ib_recv.c
ib_ring.c
ib_send.c
ib_stats.c
ib_sysctl.c
ib.c
ib.h
info.c
info.h
Kconfig
loop.c
loop.h
Makefile
message.c
page.c
rdma_transport.c
rdma_transport.h
rdma.c
rds.h RDS: TCP: fix race windows in send-path quiescence by rds_tcp_accept_one() 2016-06-07 15:10:15 -07:00
recv.c
send.c RDS: TCP: Retransmit half-sent datagrams when switching sockets in rds_tcp_reset_callbacks 2016-06-07 15:10:15 -07:00
stats.c
sysctl.c
tcp_connect.c RDS: TCP: fix race windows in send-path quiescence by rds_tcp_accept_one() 2016-06-07 15:10:15 -07:00
tcp_listen.c RDS: TCP: fix race windows in send-path quiescence by rds_tcp_accept_one() 2016-06-07 15:10:15 -07:00
tcp_recv.c
tcp_send.c
tcp_stats.c
tcp.c RDS: TCP: fix race windows in send-path quiescence by rds_tcp_accept_one() 2016-06-07 15:10:15 -07:00
tcp.h RDS: TCP: Add/use rds_tcp_reset_callbacks to reset tcp socket safely 2016-06-07 15:10:15 -07:00
threads.c RDS: TCP: fix race windows in send-path quiescence by rds_tcp_accept_one() 2016-06-07 15:10:15 -07:00
transport.c