• Jakub Sitnicki's avatar
    bpf, sockmap: Check for any of tcp_bpf_prots when cloning a listener · ddce1e09
    Jakub Sitnicki authored
    A listening socket linked to a sockmap has its sk_prot overridden. It
    points to one of the struct proto variants in tcp_bpf_prots. The variant
    depends on the socket's family and which sockmap programs are attached.
    
    A child socket cloned from a TCP listener initially inherits their sk_prot.
    But before cloning is finished, we restore the child's proto to the
    listener's original non-tcp_bpf_prots one. This happens in
    tcp_create_openreq_child -> tcp_bpf_clone.
    
    Today, in tcp_bpf_clone we detect if the child's proto should be restored
    by checking only for the TCP_BPF_BASE proto variant. This is not
    correct. The sk_prot of listening socket linked to a sockmap can point to
    to any variant in tcp_bpf_prots.
    
    If the listeners sk_prot happens to be not the TCP_BPF_BASE variant, then
    the child socket unintentionally is left if the inherited sk_prot by
    tcp_bpf_clone.
    
    This leads to issues like infinite recursion on close [1], because the
    child state is otherwise not set up for use with tcp_bpf_prot operations.
    
    Adjust the check in tcp_bpf_clone to detect all of tcp_bpf_prots variants.
    
    Note that it wouldn't be sufficient to check the socket state when
    overriding the sk_prot in tcp_bpf_update_proto in order to always use the
    TCP_BPF_BASE variant for listening sockets. Since commit
    b8b8315e ("bpf, sockmap: Remove unhash handler for BPF sockmap usage")
    it is possible for a socket to transition to TCP_LISTEN state while already
    linked to a sockmap, e.g. connect() -> insert into map ->
    connect(AF_UNSPEC) -> listen().
    
    [1]: https://lore.kernel.org/all/00000000000073b14905ef2e7401@google.com/
    
    Fixes: e8025155 ("tcp_bpf: Don't let child socket inherit parent protocol ops on copy")
    Reported-by: syzbot+04c21ed96d861dccc5cd@syzkaller.appspotmail.com
    Signed-off-by: default avatarJakub Sitnicki <jakub@cloudflare.com>
    Acked-by: default avatarJohn Fastabend <john.fastabend@gmail.com>
    Link: https://lore.kernel.org/r/20230113-sockmap-fix-v2-2-1e0ee7ac2f90@cloudflare.comSigned-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
    ddce1e09
tcp_bpf.c 15 KB