mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-08 20:07:46 +09:00
mptcp: annotate lockless accesses to sk->sk_err
[ Upstream commit9ae8e5ad99] mptcp_poll() reads sk->sk_err without socket lock held/owned. Add READ_ONCE() and WRITE_ONCE() to avoid load/store tearing. Signed-off-by: Eric Dumazet <edumazet@google.com> Signed-off-by: David S. Miller <davem@davemloft.net> Stable-dep-of:d5fbeff1ab("mptcp: move __mptcp_error_report in protocol.c") Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
09b6fdf7a1
commit
c1432ece79
@@ -2047,7 +2047,7 @@ static int mptcp_event_put_token_and_ssk(struct sk_buff *skb,
|
|||||||
nla_put_s32(skb, MPTCP_ATTR_IF_IDX, ssk->sk_bound_dev_if))
|
nla_put_s32(skb, MPTCP_ATTR_IF_IDX, ssk->sk_bound_dev_if))
|
||||||
return -EMSGSIZE;
|
return -EMSGSIZE;
|
||||||
|
|
||||||
sk_err = ssk->sk_err;
|
sk_err = READ_ONCE(ssk->sk_err);
|
||||||
if (sk_err && sk->sk_state == TCP_ESTABLISHED &&
|
if (sk_err && sk->sk_state == TCP_ESTABLISHED &&
|
||||||
nla_put_u8(skb, MPTCP_ATTR_ERROR, sk_err))
|
nla_put_u8(skb, MPTCP_ATTR_ERROR, sk_err))
|
||||||
return -EMSGSIZE;
|
return -EMSGSIZE;
|
||||||
|
|||||||
@@ -2517,15 +2517,15 @@ static void mptcp_check_fastclose(struct mptcp_sock *msk)
|
|||||||
/* Mirror the tcp_reset() error propagation */
|
/* Mirror the tcp_reset() error propagation */
|
||||||
switch (sk->sk_state) {
|
switch (sk->sk_state) {
|
||||||
case TCP_SYN_SENT:
|
case TCP_SYN_SENT:
|
||||||
sk->sk_err = ECONNREFUSED;
|
WRITE_ONCE(sk->sk_err, ECONNREFUSED);
|
||||||
break;
|
break;
|
||||||
case TCP_CLOSE_WAIT:
|
case TCP_CLOSE_WAIT:
|
||||||
sk->sk_err = EPIPE;
|
WRITE_ONCE(sk->sk_err, EPIPE);
|
||||||
break;
|
break;
|
||||||
case TCP_CLOSE:
|
case TCP_CLOSE:
|
||||||
return;
|
return;
|
||||||
default:
|
default:
|
||||||
sk->sk_err = ECONNRESET;
|
WRITE_ONCE(sk->sk_err, ECONNRESET);
|
||||||
}
|
}
|
||||||
|
|
||||||
inet_sk_state_store(sk, TCP_CLOSE);
|
inet_sk_state_store(sk, TCP_CLOSE);
|
||||||
@@ -3893,7 +3893,7 @@ static __poll_t mptcp_poll(struct file *file, struct socket *sock,
|
|||||||
|
|
||||||
/* This barrier is coupled with smp_wmb() in __mptcp_error_report() */
|
/* This barrier is coupled with smp_wmb() in __mptcp_error_report() */
|
||||||
smp_rmb();
|
smp_rmb();
|
||||||
if (sk->sk_err)
|
if (READ_ONCE(sk->sk_err))
|
||||||
mask |= EPOLLERR;
|
mask |= EPOLLERR;
|
||||||
|
|
||||||
return mask;
|
return mask;
|
||||||
|
|||||||
@@ -1248,7 +1248,7 @@ fallback:
|
|||||||
subflow->reset_reason = MPTCP_RST_EMPTCP;
|
subflow->reset_reason = MPTCP_RST_EMPTCP;
|
||||||
|
|
||||||
reset:
|
reset:
|
||||||
ssk->sk_err = EBADMSG;
|
WRITE_ONCE(ssk->sk_err, EBADMSG);
|
||||||
tcp_set_state(ssk, TCP_CLOSE);
|
tcp_set_state(ssk, TCP_CLOSE);
|
||||||
while ((skb = skb_peek(&ssk->sk_receive_queue)))
|
while ((skb = skb_peek(&ssk->sk_receive_queue)))
|
||||||
sk_eat_skb(ssk, skb);
|
sk_eat_skb(ssk, skb);
|
||||||
@@ -1332,7 +1332,7 @@ void __mptcp_error_report(struct sock *sk)
|
|||||||
ssk_state = inet_sk_state_load(ssk);
|
ssk_state = inet_sk_state_load(ssk);
|
||||||
if (ssk_state == TCP_CLOSE && !sock_flag(sk, SOCK_DEAD))
|
if (ssk_state == TCP_CLOSE && !sock_flag(sk, SOCK_DEAD))
|
||||||
inet_sk_state_store(sk, ssk_state);
|
inet_sk_state_store(sk, ssk_state);
|
||||||
sk->sk_err = -err;
|
WRITE_ONCE(sk->sk_err, -err);
|
||||||
|
|
||||||
/* This barrier is coupled with smp_rmb() in mptcp_poll() */
|
/* This barrier is coupled with smp_rmb() in mptcp_poll() */
|
||||||
smp_wmb();
|
smp_wmb();
|
||||||
|
|||||||
Reference in New Issue
Block a user