net, sk_msg: Annotate lockless access to sk_prot on clone
authorJakub Sitnicki <jakub@cloudflare.com>
Tue, 18 Feb 2020 17:10:13 +0000 (17:10 +0000)
committerDaniel Borkmann <daniel@iogearbox.net>
Fri, 21 Feb 2020 21:29:45 +0000 (22:29 +0100)
commitb8e202d1d1d0f182f01062804efb523ea9a9008c
tree57a1c1d075e2d470fd9c1487744286c2f3bed747
parente42da4c62abb547d9c9138e0e7fcd1f36057b5e8
net, sk_msg: Annotate lockless access to sk_prot on clone

sk_msg and ULP frameworks override protocol callbacks pointer in
sk->sk_prot, while tcp accesses it locklessly when cloning the listening
socket, that is with neither sk_lock nor sk_callback_lock held.

Once we enable use of listening sockets with sockmap (and hence sk_msg),
there will be shared access to sk->sk_prot if socket is getting cloned
while being inserted/deleted to/from the sockmap from another CPU:

Read side:

tcp_v4_rcv
  sk = __inet_lookup_skb(...)
  tcp_check_req(sk)
    inet_csk(sk)->icsk_af_ops->syn_recv_sock
      tcp_v4_syn_recv_sock
        tcp_create_openreq_child
          inet_csk_clone_lock
            sk_clone_lock
              READ_ONCE(sk->sk_prot)

Write side:

sock_map_ops->map_update_elem
  sock_map_update_elem
    sock_map_update_common
      sock_map_link_no_progs
        tcp_bpf_init
          tcp_bpf_update_sk_prot
            sk_psock_update_proto
              WRITE_ONCE(sk->sk_prot, ops)

sock_map_ops->map_delete_elem
  sock_map_delete_elem
    __sock_map_delete
     sock_map_unref
       sk_psock_put
         sk_psock_drop
           sk_psock_restore_proto
             tcp_update_ulp
               WRITE_ONCE(sk->sk_prot, proto)

Mark the shared access with READ_ONCE/WRITE_ONCE annotations.

Signed-off-by: Jakub Sitnicki <jakub@cloudflare.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Link: https://lore.kernel.org/bpf/20200218171023.844439-2-jakub@cloudflare.com
include/linux/skmsg.h
net/core/sock.c
net/ipv4/tcp_bpf.c
net/ipv4/tcp_ulp.c
net/tls/tls_main.c