Skip to content

Commit 6b9831b

Browse files
Paolo Abenikuba-moo
authored andcommitted
mptcp: add annotations around sk->sk_shutdown accesses
Christoph reported the mptcp variant of a recently addressed plain TCP issue. Similar to commit e14cadf ("tcp: add annotations around sk->sk_shutdown accesses") add READ/WRITE ONCE annotations to silence KCSAN reports around lockless sk_shutdown access. Fixes: 71ba088 ("mptcp: cleanup accept and poll") Reported-by: Christoph Paasch <cpaasch@apple.com> Closes: multipath-tcp/mptcp_net-next#401 Reviewed-by: Mat Martineau <martineau@kernel.org> Signed-off-by: Paolo Abeni <pabeni@redhat.com> Signed-off-by: Mat Martineau <martineau@kernel.org> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
1 parent 1b1b43e commit 6b9831b

1 file changed

Lines changed: 16 additions & 13 deletions

File tree

net/mptcp/protocol.c

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -603,7 +603,7 @@ static bool mptcp_check_data_fin(struct sock *sk)
603603
WRITE_ONCE(msk->ack_seq, msk->ack_seq + 1);
604604
WRITE_ONCE(msk->rcv_data_fin, 0);
605605

606-
sk->sk_shutdown |= RCV_SHUTDOWN;
606+
WRITE_ONCE(sk->sk_shutdown, sk->sk_shutdown | RCV_SHUTDOWN);
607607
smp_mb__before_atomic(); /* SHUTDOWN must be visible first */
608608

609609
switch (sk->sk_state) {
@@ -910,7 +910,7 @@ static void mptcp_check_for_eof(struct mptcp_sock *msk)
910910
/* hopefully temporary hack: propagate shutdown status
911911
* to msk, when all subflows agree on it
912912
*/
913-
sk->sk_shutdown |= RCV_SHUTDOWN;
913+
WRITE_ONCE(sk->sk_shutdown, sk->sk_shutdown | RCV_SHUTDOWN);
914914

915915
smp_mb__before_atomic(); /* SHUTDOWN must be visible first */
916916
sk->sk_data_ready(sk);
@@ -2526,7 +2526,7 @@ static void mptcp_check_fastclose(struct mptcp_sock *msk)
25262526
}
25272527

25282528
inet_sk_state_store(sk, TCP_CLOSE);
2529-
sk->sk_shutdown = SHUTDOWN_MASK;
2529+
WRITE_ONCE(sk->sk_shutdown, SHUTDOWN_MASK);
25302530
smp_mb__before_atomic(); /* SHUTDOWN must be visible first */
25312531
set_bit(MPTCP_WORK_CLOSE_SUBFLOW, &msk->flags);
25322532

@@ -2958,7 +2958,7 @@ bool __mptcp_close(struct sock *sk, long timeout)
29582958
bool do_cancel_work = false;
29592959
int subflows_alive = 0;
29602960

2961-
sk->sk_shutdown = SHUTDOWN_MASK;
2961+
WRITE_ONCE(sk->sk_shutdown, SHUTDOWN_MASK);
29622962

29632963
if ((1 << sk->sk_state) & (TCPF_LISTEN | TCPF_CLOSE)) {
29642964
mptcp_listen_inuse_dec(sk);
@@ -3101,7 +3101,7 @@ static int mptcp_disconnect(struct sock *sk, int flags)
31013101
mptcp_pm_data_reset(msk);
31023102
mptcp_ca_reset(sk);
31033103

3104-
sk->sk_shutdown = 0;
3104+
WRITE_ONCE(sk->sk_shutdown, 0);
31053105
sk_error_report(sk);
31063106
return 0;
31073107
}
@@ -3806,9 +3806,6 @@ static __poll_t mptcp_check_writeable(struct mptcp_sock *msk)
38063806
{
38073807
struct sock *sk = (struct sock *)msk;
38083808

3809-
if (unlikely(sk->sk_shutdown & SEND_SHUTDOWN))
3810-
return EPOLLOUT | EPOLLWRNORM;
3811-
38123809
if (sk_stream_is_writeable(sk))
38133810
return EPOLLOUT | EPOLLWRNORM;
38143811

@@ -3826,6 +3823,7 @@ static __poll_t mptcp_poll(struct file *file, struct socket *sock,
38263823
struct sock *sk = sock->sk;
38273824
struct mptcp_sock *msk;
38283825
__poll_t mask = 0;
3826+
u8 shutdown;
38293827
int state;
38303828

38313829
msk = mptcp_sk(sk);
@@ -3842,17 +3840,22 @@ static __poll_t mptcp_poll(struct file *file, struct socket *sock,
38423840
return inet_csk_listen_poll(ssock->sk);
38433841
}
38443842

3843+
shutdown = READ_ONCE(sk->sk_shutdown);
3844+
if (shutdown == SHUTDOWN_MASK || state == TCP_CLOSE)
3845+
mask |= EPOLLHUP;
3846+
if (shutdown & RCV_SHUTDOWN)
3847+
mask |= EPOLLIN | EPOLLRDNORM | EPOLLRDHUP;
3848+
38453849
if (state != TCP_SYN_SENT && state != TCP_SYN_RECV) {
38463850
mask |= mptcp_check_readable(msk);
3847-
mask |= mptcp_check_writeable(msk);
3851+
if (shutdown & SEND_SHUTDOWN)
3852+
mask |= EPOLLOUT | EPOLLWRNORM;
3853+
else
3854+
mask |= mptcp_check_writeable(msk);
38483855
} else if (state == TCP_SYN_SENT && inet_sk(sk)->defer_connect) {
38493856
/* cf tcp_poll() note about TFO */
38503857
mask |= EPOLLOUT | EPOLLWRNORM;
38513858
}
3852-
if (sk->sk_shutdown == SHUTDOWN_MASK || state == TCP_CLOSE)
3853-
mask |= EPOLLHUP;
3854-
if (sk->sk_shutdown & RCV_SHUTDOWN)
3855-
mask |= EPOLLIN | EPOLLRDNORM | EPOLLRDHUP;
38563859

38573860
/* This barrier is coupled with smp_wmb() in __mptcp_error_report() */
38583861
smp_rmb();

0 commit comments

Comments
 (0)