]> git.baikalelectronics.ru Git - kernel.git/commitdiff
mptcp: annotate lockless accesses to sk->sk_err
authorEric Dumazet <edumazet@google.com>
Wed, 15 Mar 2023 20:57:45 +0000 (20:57 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 10 Oct 2023 20:00:34 +0000 (22:00 +0200)
[ Upstream commit 9ae8e5ad99b8ebcd3d3dd46075f3825e6f08f063 ]

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: d5fbeff1ab81 ("mptcp: move __mptcp_error_report in protocol.c")
Signed-off-by: Sasha Levin <sashal@kernel.org>
net/mptcp/pm_netlink.c
net/mptcp/protocol.c
net/mptcp/subflow.c

index 9127a7fd5269c0b1e7c058e2c263eccb62c0c1c0..5d845fcf3d09e10a05c3d910b6de6e5140c37c26 100644 (file)
@@ -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))
                return -EMSGSIZE;
 
-       sk_err = ssk->sk_err;
+       sk_err = READ_ONCE(ssk->sk_err);
        if (sk_err && sk->sk_state == TCP_ESTABLISHED &&
            nla_put_u8(skb, MPTCP_ATTR_ERROR, sk_err))
                return -EMSGSIZE;
index 60e65f6325c3cbfb70c34bbf9e310185c2733b81..84f107854eac9b3ec7af5c39f7692d5fc824897c 100644 (file)
@@ -2517,15 +2517,15 @@ static void mptcp_check_fastclose(struct mptcp_sock *msk)
        /* Mirror the tcp_reset() error propagation */
        switch (sk->sk_state) {
        case TCP_SYN_SENT:
-               sk->sk_err = ECONNREFUSED;
+               WRITE_ONCE(sk->sk_err, ECONNREFUSED);
                break;
        case TCP_CLOSE_WAIT:
-               sk->sk_err = EPIPE;
+               WRITE_ONCE(sk->sk_err, EPIPE);
                break;
        case TCP_CLOSE:
                return;
        default:
-               sk->sk_err = ECONNRESET;
+               WRITE_ONCE(sk->sk_err, ECONNRESET);
        }
 
        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() */
        smp_rmb();
-       if (sk->sk_err)
+       if (READ_ONCE(sk->sk_err))
                mask |= EPOLLERR;
 
        return mask;
index 168dced2434b348c83ac22341d5b26ac8c7777f2..032661c8273f2f18881043b7400d802f61e7e19d 100644 (file)
@@ -1248,7 +1248,7 @@ fallback:
                        subflow->reset_reason = MPTCP_RST_EMPTCP;
 
 reset:
-                       ssk->sk_err = EBADMSG;
+                       WRITE_ONCE(ssk->sk_err, EBADMSG);
                        tcp_set_state(ssk, TCP_CLOSE);
                        while ((skb = skb_peek(&ssk->sk_receive_queue)))
                                sk_eat_skb(ssk, skb);
@@ -1332,7 +1332,7 @@ void __mptcp_error_report(struct sock *sk)
                ssk_state = inet_sk_state_load(ssk);
                if (ssk_state == TCP_CLOSE && !sock_flag(sk, SOCK_DEAD))
                        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() */
                smp_wmb();