Commit 9201f60a authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

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: default avatarJakub Kicinski <kuba@kernel.org>
parents 1208b93d 71b7786e
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -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;
+2 −0
Original line number Diff line number Diff line
@@ -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;
+2 −2
Original line number Diff line number Diff line
@@ -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);
+3 −0
Original line number Diff line number Diff line
@@ -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;
+2 −2
Original line number Diff line number Diff line
@@ -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);
Loading