FAILED: patch "[PATCH] net/ulp: prevent ULP without clone op from entering the" failed to apply to 5.4-stable tree
Subsystems (3)
[email protected]
maintainerThe patch below does not apply to the 5.4-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
Possible dependencies:
2c02d41d71f9 ("net/ulp: prevent ULP without clone op from entering the LISTEN status") e276d62dcfde ("net/ulp: remove SOCK_SUPPORT_ZC from tls sockets") e7049395b1c3 ("dccp/tcp: Remove an unused argument in inet_csk_listen_start().") 53632e111946 ("bpf: selftest: Use bpf_sk_storage in FENTRY/FEXIT/RAW_TP")
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 2c02d41d71f90a5168391b6a5f2954112ba2307c Mon Sep 17 00:00:00 2001
From: Paolo Abeni <[email protected]>
Date: Tue, 3 Jan 2023 12:19:17 +0100
Subject: [PATCH] net/ulp: prevent ULP without clone op from entering the
LISTEN status
When an ULP-enabled socket enters the LISTEN status, the listener ULP data pointer is copied inside the child/accepted sockets by sk_clone_lock().
The relevant ULP can take care of de-duplicating the context pointer via the clone() operation, but only MPTCP and SMC implement such op.
Other ULPs may end-up with a double-free at socket disposal time.
We can't simply clear the ULP data at clone time, as TLS replaces the socket ops with custom ones assuming a valid TLS ULP context is available.
Instead completely prevent clone-less ULP sockets from entering the LISTEN status.
net/ipv4/inet_connection_sock.c +14 -0
@@ -1200,12 +1200,26 @@ void inet_csk_prepare_forced_close(struct sock *sk) }EXPORT_SYMBOL (inet_csk_prepare_forced_close); +static int inet_ulp_can_listen (const struct sock *sk) +{ +const struct inet_connection_sock *icsk =inet_csk (sk); + +if (icsk->icsk_ulp_ops && !icsk->icsk_ulp_ops->clone) +return -EINVAL ; + +return 0 ; +} +int inet_csk_listen_start (struct sock *sk) {struct inet_connection_sock *icsk =inet_csk (sk);struct inet_sock *inet =inet_sk (sk);int err; + err =inet_ulp_can_listen (sk); +if (unlikely (err)) +return err; +reqsk_queue_alloc (&icsk->icsk_accept_queue); sk->sk_ack_backlog =0 ;
net/ipv4/tcp_ulp.c +4 -0
@@ -139,6 +139,10 @@ static int __tcp_set_ulp(struct sock *sk, const struct tcp_ulp_ops *ulp_ops)if (sk->sk_socket)clear_bit (SOCK_SUPPORT_ZC , &sk->sk_socket->flags); + err = -EINVAL ; +if (!ulp_ops->clone && sk->sk_state ==TCP_LISTEN ) + goto out_err; + err = ulp_ops->init (sk);if (err) goto out_err;