Merge branch 'a-few-corrections-for-sock_support_zc'
Pavel Begunkov says: ==================== a few corrections for SOCK_SUPPORT_ZC There are several places/cases that got overlooked in regards to SOCK_SUPPORT_ZC. We're lacking the flag for IPv6 UDP sockets and accepted TCP sockets. We also should clear the flag when someone tries to hijack a socket by replacing the ->sk_prot callbacks. ==================== Link: https://lore.kernel.org/r/cover.1666825799.git.asml.silence@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
commit
9201f60a19
@ -1889,6 +1889,13 @@ void sock_kfree_s(struct sock *sk, void *mem, int size);
|
||||
void sock_kzfree_s(struct sock *sk, void *mem, int size);
|
||||
void sk_send_sigurg(struct sock *sk);
|
||||
|
||||
static inline void sock_replace_proto(struct sock *sk, struct proto *proto)
|
||||
{
|
||||
if (sk->sk_socket)
|
||||
clear_bit(SOCK_SUPPORT_ZC, &sk->sk_socket->flags);
|
||||
WRITE_ONCE(sk->sk_prot, proto);
|
||||
}
|
||||
|
||||
struct sockcm_cookie {
|
||||
u64 transmit_time;
|
||||
u32 mark;
|
||||
|
@ -754,6 +754,8 @@ int inet_accept(struct socket *sock, struct socket *newsock, int flags,
|
||||
(TCPF_ESTABLISHED | TCPF_SYN_RECV |
|
||||
TCPF_CLOSE_WAIT | TCPF_CLOSE)));
|
||||
|
||||
if (test_bit(SOCK_SUPPORT_ZC, &sock->flags))
|
||||
set_bit(SOCK_SUPPORT_ZC, &newsock->flags);
|
||||
sock_graft(sk2, newsock);
|
||||
|
||||
newsock->state = SS_CONNECTED;
|
||||
|
@ -607,7 +607,7 @@ int tcp_bpf_update_proto(struct sock *sk, struct sk_psock *psock, bool restore)
|
||||
} else {
|
||||
sk->sk_write_space = psock->saved_write_space;
|
||||
/* Pairs with lockless read in sk_clone_lock() */
|
||||
WRITE_ONCE(sk->sk_prot, psock->sk_proto);
|
||||
sock_replace_proto(sk, psock->sk_proto);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -620,7 +620,7 @@ int tcp_bpf_update_proto(struct sock *sk, struct sk_psock *psock, bool restore)
|
||||
}
|
||||
|
||||
/* Pairs with lockless read in sk_clone_lock() */
|
||||
WRITE_ONCE(sk->sk_prot, &tcp_bpf_prots[family][config]);
|
||||
sock_replace_proto(sk, &tcp_bpf_prots[family][config]);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(tcp_bpf_update_proto);
|
||||
|
@ -136,6 +136,9 @@ static int __tcp_set_ulp(struct sock *sk, const struct tcp_ulp_ops *ulp_ops)
|
||||
if (icsk->icsk_ulp_ops)
|
||||
goto out_err;
|
||||
|
||||
if (sk->sk_socket)
|
||||
clear_bit(SOCK_SUPPORT_ZC, &sk->sk_socket->flags);
|
||||
|
||||
err = ulp_ops->init(sk);
|
||||
if (err)
|
||||
goto out_err;
|
||||
|
@ -141,14 +141,14 @@ int udp_bpf_update_proto(struct sock *sk, struct sk_psock *psock, bool restore)
|
||||
|
||||
if (restore) {
|
||||
sk->sk_write_space = psock->saved_write_space;
|
||||
WRITE_ONCE(sk->sk_prot, psock->sk_proto);
|
||||
sock_replace_proto(sk, psock->sk_proto);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (sk->sk_family == AF_INET6)
|
||||
udp_bpf_check_v6_needs_rebuild(psock->sk_proto);
|
||||
|
||||
WRITE_ONCE(sk->sk_prot, &udp_bpf_prots[family]);
|
||||
sock_replace_proto(sk, &udp_bpf_prots[family]);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(udp_bpf_update_proto);
|
||||
|
@ -66,6 +66,7 @@ int udpv6_init_sock(struct sock *sk)
|
||||
{
|
||||
skb_queue_head_init(&udp_sk(sk)->reader_queue);
|
||||
sk->sk_destruct = udpv6_destruct_sock;
|
||||
set_bit(SOCK_SUPPORT_ZC, &sk->sk_socket->flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -145,12 +145,12 @@ int unix_dgram_bpf_update_proto(struct sock *sk, struct sk_psock *psock, bool re
|
||||
|
||||
if (restore) {
|
||||
sk->sk_write_space = psock->saved_write_space;
|
||||
WRITE_ONCE(sk->sk_prot, psock->sk_proto);
|
||||
sock_replace_proto(sk, psock->sk_proto);
|
||||
return 0;
|
||||
}
|
||||
|
||||
unix_dgram_bpf_check_needs_rebuild(psock->sk_proto);
|
||||
WRITE_ONCE(sk->sk_prot, &unix_dgram_bpf_prot);
|
||||
sock_replace_proto(sk, &unix_dgram_bpf_prot);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -158,12 +158,12 @@ int unix_stream_bpf_update_proto(struct sock *sk, struct sk_psock *psock, bool r
|
||||
{
|
||||
if (restore) {
|
||||
sk->sk_write_space = psock->saved_write_space;
|
||||
WRITE_ONCE(sk->sk_prot, psock->sk_proto);
|
||||
sock_replace_proto(sk, psock->sk_proto);
|
||||
return 0;
|
||||
}
|
||||
|
||||
unix_stream_bpf_check_needs_rebuild(psock->sk_proto);
|
||||
WRITE_ONCE(sk->sk_prot, &unix_stream_bpf_prot);
|
||||
sock_replace_proto(sk, &unix_stream_bpf_prot);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user