All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 5.10 0/5] Backport complete patchset for call inet6_destroy_sock() in IPv6 sk->sk_destruct()
@ 2023-04-04  9:24 Ziyang Xuan
  2023-04-04  9:24 ` [PATCH 5.10 1/5] udp: Call inet6_destroy_sock() in setsockopt(IPV6_ADDRFORM) Ziyang Xuan
                   ` (4 more replies)
  0 siblings, 5 replies; 10+ messages in thread
From: Ziyang Xuan @ 2023-04-04  9:24 UTC (permalink / raw)
  To: gregkh, stable, davem, kuznet, yoshfuji, kuba, kuniyu; +Cc: netdev

5.10 LTS has backported commit ca43ccf41224 ("dccp/tcp: Avoid negative
sk_forward_alloc by ipv6_pinfo.pktoptions.") and commit 62ec33b44e0f ("net:
Remove WARN_ON_ONCE(sk->sk_forward_alloc) from sk_stream_kill_queues()."),
but these are incomplete. There are some patches that have not been
backported including key commit d38afeec26ed ("tcp/udp: Call
inet6_destroy_sock() in IPv6 sk->sk_destruct().") and commit b5fc29233d28
("inet6: Remove inet6_destroy_sock() in sk->sk_prot->destroy()."). Without
them, there will be some memory leak bugs.

Backport complete patchset for call inet6_destroy_sock() in IPv6
sk->sk_destruct().

Kuniyuki Iwashima (5):
  udp: Call inet6_destroy_sock() in setsockopt(IPV6_ADDRFORM).
  tcp/udp: Call inet6_destroy_sock() in IPv6 sk->sk_destruct().
  inet6: Remove inet6_destroy_sock() in sk->sk_prot->destroy().
  dccp: Call inet6_destroy_sock() via sk->sk_destruct().
  sctp: Call inet6_destroy_sock() via sk->sk_destruct().

 include/net/ipv6.h       |  2 ++
 include/net/udp.h        |  2 +-
 include/net/udplite.h    |  8 --------
 net/dccp/dccp.h          |  1 +
 net/dccp/ipv6.c          | 15 ++++++++-------
 net/dccp/proto.c         |  8 +++++++-
 net/ipv4/udp.c           |  9 ++++++---
 net/ipv4/udplite.c       |  8 ++++++++
 net/ipv6/af_inet6.c      | 15 ++++++++++++++-
 net/ipv6/ipv6_sockglue.c | 20 ++++++++------------
 net/ipv6/ping.c          |  6 ------
 net/ipv6/raw.c           |  2 --
 net/ipv6/tcp_ipv6.c      |  8 +-------
 net/ipv6/udp.c           | 17 ++++++++++++++---
 net/ipv6/udp_impl.h      |  1 +
 net/ipv6/udplite.c       |  9 ++++++++-
 net/l2tp/l2tp_ip6.c      |  2 --
 net/mptcp/protocol.c     |  7 -------
 net/sctp/socket.c        | 29 +++++++++++++++++++++--------
 19 files changed, 100 insertions(+), 69 deletions(-)

-- 
2.25.1


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 5.10 1/5] udp: Call inet6_destroy_sock() in setsockopt(IPV6_ADDRFORM).
  2023-04-04  9:24 [PATCH 5.10 0/5] Backport complete patchset for call inet6_destroy_sock() in IPv6 sk->sk_destruct() Ziyang Xuan
@ 2023-04-04  9:24 ` Ziyang Xuan
  2023-04-18 10:21   ` Greg KH
  2023-04-04  9:24 ` [PATCH 5.10 2/5] tcp/udp: Call inet6_destroy_sock() in IPv6 sk->sk_destruct() Ziyang Xuan
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 10+ messages in thread
From: Ziyang Xuan @ 2023-04-04  9:24 UTC (permalink / raw)
  To: gregkh, stable, davem, kuznet, yoshfuji, kuba, kuniyu; +Cc: netdev

From: Kuniyuki Iwashima <kuniyu@amazon.com>

commit 21985f43376cee092702d6cb963ff97a9d2ede68 upstream.

Commit 4b340ae20d0e ("IPv6: Complete IPV6_DONTFRAG support") forgot
to add a change to free inet6_sk(sk)->rxpmtu while converting an IPv6
socket into IPv4 with IPV6_ADDRFORM.  After conversion, sk_prot is
changed to udp_prot and ->destroy() never cleans it up, resulting in
a memory leak.

This is due to the discrepancy between inet6_destroy_sock() and
IPV6_ADDRFORM, so let's call inet6_destroy_sock() from IPV6_ADDRFORM
to remove the difference.

However, this is not enough for now because rxpmtu can be changed
without lock_sock() after commit 03485f2adcde ("udpv6: Add lockless
sendmsg() support").  We will fix this case in the following patch.

Note we will rename inet6_destroy_sock() to inet6_cleanup_sock() and
remove unnecessary inet6_destroy_sock() calls in sk_prot->destroy()
in the future.

Fixes: 4b340ae20d0e ("IPv6: Complete IPV6_DONTFRAG support")
Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Ziyang Xuan <william.xuanziyang@huawei.com>
---
 include/net/ipv6.h       |  1 +
 net/ipv6/af_inet6.c      |  6 ++++++
 net/ipv6/ipv6_sockglue.c | 20 ++++++++------------
 3 files changed, 15 insertions(+), 12 deletions(-)

diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index 89ce8a50f236..5ab7616ce711 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -1109,6 +1109,7 @@ void ipv6_icmp_error(struct sock *sk, struct sk_buff *skb, int err, __be16 port,
 void ipv6_local_error(struct sock *sk, int err, struct flowi6 *fl6, u32 info);
 void ipv6_local_rxpmtu(struct sock *sk, struct flowi6 *fl6, u32 mtu);
 
+void inet6_cleanup_sock(struct sock *sk);
 int inet6_release(struct socket *sock);
 int inet6_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len);
 int inet6_getname(struct socket *sock, struct sockaddr *uaddr,
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index 4df9dc9375c8..68d456c7abf9 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -503,6 +503,12 @@ void inet6_destroy_sock(struct sock *sk)
 }
 EXPORT_SYMBOL_GPL(inet6_destroy_sock);
 
+void inet6_cleanup_sock(struct sock *sk)
+{
+	inet6_destroy_sock(sk);
+}
+EXPORT_SYMBOL_GPL(inet6_cleanup_sock);
+
 /*
  *	This does both peername and sockname.
  */
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index 2017257cb278..7b4b457a8b87 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -429,9 +429,6 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
 		if (optlen < sizeof(int))
 			goto e_inval;
 		if (val == PF_INET) {
-			struct ipv6_txoptions *opt;
-			struct sk_buff *pktopt;
-
 			if (sk->sk_type == SOCK_RAW)
 				break;
 
@@ -462,7 +459,6 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
 				break;
 			}
 
-			fl6_free_socklist(sk);
 			__ipv6_sock_mc_close(sk);
 			__ipv6_sock_ac_close(sk);
 
@@ -497,14 +493,14 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
 				sk->sk_socket->ops = &inet_dgram_ops;
 				sk->sk_family = PF_INET;
 			}
-			opt = xchg((__force struct ipv6_txoptions **)&np->opt,
-				   NULL);
-			if (opt) {
-				atomic_sub(opt->tot_len, &sk->sk_omem_alloc);
-				txopt_put(opt);
-			}
-			pktopt = xchg(&np->pktoptions, NULL);
-			kfree_skb(pktopt);
+
+			/* Disable all options not to allocate memory anymore,
+			 * but there is still a race.  See the lockless path
+			 * in udpv6_sendmsg() and ipv6_local_rxpmtu().
+			 */
+			np->rxopt.all = 0;
+
+			inet6_cleanup_sock(sk);
 
 			/*
 			 * ... and add it to the refcnt debug socks count
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 5.10 2/5] tcp/udp: Call inet6_destroy_sock() in IPv6 sk->sk_destruct().
  2023-04-04  9:24 [PATCH 5.10 0/5] Backport complete patchset for call inet6_destroy_sock() in IPv6 sk->sk_destruct() Ziyang Xuan
  2023-04-04  9:24 ` [PATCH 5.10 1/5] udp: Call inet6_destroy_sock() in setsockopt(IPV6_ADDRFORM) Ziyang Xuan
@ 2023-04-04  9:24 ` Ziyang Xuan
  2023-04-04  9:24 ` [PATCH 5.10 3/5] inet6: Remove inet6_destroy_sock() in sk->sk_prot->destroy() Ziyang Xuan
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 10+ messages in thread
From: Ziyang Xuan @ 2023-04-04  9:24 UTC (permalink / raw)
  To: gregkh, stable, davem, kuznet, yoshfuji, kuba, kuniyu; +Cc: netdev

From: Kuniyuki Iwashima <kuniyu@amazon.com>

commit d38afeec26ed4739c640bf286c270559aab2ba5f upstream.

Originally, inet6_sk(sk)->XXX were changed under lock_sock(), so we were
able to clean them up by calling inet6_destroy_sock() during the IPv6 ->
IPv4 conversion by IPV6_ADDRFORM.  However, commit 03485f2adcde ("udpv6:
Add lockless sendmsg() support") added a lockless memory allocation path,
which could cause a memory leak:

setsockopt(IPV6_ADDRFORM)                 sendmsg()
+-----------------------+                 +-------+
- do_ipv6_setsockopt(sk, ...)             - udpv6_sendmsg(sk, ...)
  - sockopt_lock_sock(sk)                   ^._ called via udpv6_prot
    - lock_sock(sk)                             before WRITE_ONCE()
  - WRITE_ONCE(sk->sk_prot, &tcp_prot)
  - inet6_destroy_sock()                    - if (!corkreq)
  - sockopt_release_sock(sk)                  - ip6_make_skb(sk, ...)
    - release_sock(sk)                          ^._ lockless fast path for
                                                    the non-corking case

                                                - __ip6_append_data(sk, ...)
                                                  - ipv6_local_rxpmtu(sk, ...)
                                                    - xchg(&np->rxpmtu, skb)
                                                      ^._ rxpmtu is never freed.

                                                - goto out_no_dst;

                                            - lock_sock(sk)

For now, rxpmtu is only the case, but not to miss the future change
and a similar bug fixed in commit e27326009a3d ("net: ping6: Fix
memleak in ipv6_renew_options()."), let's set a new function to IPv6
sk->sk_destruct() and call inet6_cleanup_sock() there.  Since the
conversion does not change sk->sk_destruct(), we can guarantee that
we can clean up IPv6 resources finally.

We can now remove all inet6_destroy_sock() calls from IPv6 protocol
specific ->destroy() functions, but such changes are invasive to
backport.  So they can be posted as a follow-up later for net-next.

Fixes: 03485f2adcde ("udpv6: Add lockless sendmsg() support")
Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Ziyang Xuan <william.xuanziyang@huawei.com>
---
 include/net/ipv6.h    |  1 +
 include/net/udp.h     |  2 +-
 include/net/udplite.h |  8 --------
 net/ipv4/udp.c        |  9 ++++++---
 net/ipv4/udplite.c    |  8 ++++++++
 net/ipv6/af_inet6.c   |  8 +++++++-
 net/ipv6/udp.c        | 15 ++++++++++++++-
 net/ipv6/udp_impl.h   |  1 +
 net/ipv6/udplite.c    |  9 ++++++++-
 9 files changed, 46 insertions(+), 15 deletions(-)

diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index 5ab7616ce711..8879c0ab0b89 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -1110,6 +1110,7 @@ void ipv6_local_error(struct sock *sk, int err, struct flowi6 *fl6, u32 info);
 void ipv6_local_rxpmtu(struct sock *sk, struct flowi6 *fl6, u32 mtu);
 
 void inet6_cleanup_sock(struct sock *sk);
+void inet6_sock_destruct(struct sock *sk);
 int inet6_release(struct socket *sock);
 int inet6_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len);
 int inet6_getname(struct socket *sock, struct sockaddr *uaddr,
diff --git a/include/net/udp.h b/include/net/udp.h
index 388e68c7bca0..e2550a4547a7 100644
--- a/include/net/udp.h
+++ b/include/net/udp.h
@@ -268,7 +268,7 @@ static inline bool udp_sk_bound_dev_eq(struct net *net, int bound_dev_if,
 }
 
 /* net/ipv4/udp.c */
-void udp_destruct_sock(struct sock *sk);
+void udp_destruct_common(struct sock *sk);
 void skb_consume_udp(struct sock *sk, struct sk_buff *skb, int len);
 int __udp_enqueue_schedule_skb(struct sock *sk, struct sk_buff *skb);
 void udp_skb_destructor(struct sock *sk, struct sk_buff *skb);
diff --git a/include/net/udplite.h b/include/net/udplite.h
index 9185e45b997f..c59ba86668af 100644
--- a/include/net/udplite.h
+++ b/include/net/udplite.h
@@ -24,14 +24,6 @@ static __inline__ int udplite_getfrag(void *from, char *to, int  offset,
 	return copy_from_iter_full(to, len, &msg->msg_iter) ? 0 : -EFAULT;
 }
 
-/* Designate sk as UDP-Lite socket */
-static inline int udplite_sk_init(struct sock *sk)
-{
-	udp_init_sock(sk);
-	udp_sk(sk)->pcflag = UDPLITE_BIT;
-	return 0;
-}
-
 /*
  * 	Checksumming routines
  */
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index b093daaa3deb..f0db66e415bd 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -1582,7 +1582,7 @@ int __udp_enqueue_schedule_skb(struct sock *sk, struct sk_buff *skb)
 }
 EXPORT_SYMBOL_GPL(__udp_enqueue_schedule_skb);
 
-void udp_destruct_sock(struct sock *sk)
+void udp_destruct_common(struct sock *sk)
 {
 	/* reclaim completely the forward allocated memory */
 	struct udp_sock *up = udp_sk(sk);
@@ -1595,10 +1595,14 @@ void udp_destruct_sock(struct sock *sk)
 		kfree_skb(skb);
 	}
 	udp_rmem_release(sk, total, 0, true);
+}
+EXPORT_SYMBOL_GPL(udp_destruct_common);
 
+static void udp_destruct_sock(struct sock *sk)
+{
+	udp_destruct_common(sk);
 	inet_sock_destruct(sk);
 }
-EXPORT_SYMBOL_GPL(udp_destruct_sock);
 
 int udp_init_sock(struct sock *sk)
 {
@@ -1606,7 +1610,6 @@ int udp_init_sock(struct sock *sk)
 	sk->sk_destruct = udp_destruct_sock;
 	return 0;
 }
-EXPORT_SYMBOL_GPL(udp_init_sock);
 
 void skb_consume_udp(struct sock *sk, struct sk_buff *skb, int len)
 {
diff --git a/net/ipv4/udplite.c b/net/ipv4/udplite.c
index bd8773b49e72..cfb36655a5fd 100644
--- a/net/ipv4/udplite.c
+++ b/net/ipv4/udplite.c
@@ -17,6 +17,14 @@
 struct udp_table 	udplite_table __read_mostly;
 EXPORT_SYMBOL(udplite_table);
 
+/* Designate sk as UDP-Lite socket */
+static int udplite_sk_init(struct sock *sk)
+{
+	udp_init_sock(sk);
+	udp_sk(sk)->pcflag = UDPLITE_BIT;
+	return 0;
+}
+
 static int udplite_rcv(struct sk_buff *skb)
 {
 	return __udp4_lib_rcv(skb, &udplite_table, IPPROTO_UDPLITE);
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index 68d456c7abf9..5846e386221f 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -107,6 +107,12 @@ static __inline__ struct ipv6_pinfo *inet6_sk_generic(struct sock *sk)
 	return (struct ipv6_pinfo *)(((u8 *)sk) + offset);
 }
 
+void inet6_sock_destruct(struct sock *sk)
+{
+	inet6_cleanup_sock(sk);
+	inet_sock_destruct(sk);
+}
+
 static int inet6_create(struct net *net, struct socket *sock, int protocol,
 			int kern)
 {
@@ -199,7 +205,7 @@ static int inet6_create(struct net *net, struct socket *sock, int protocol,
 			inet->hdrincl = 1;
 	}
 
-	sk->sk_destruct		= inet_sock_destruct;
+	sk->sk_destruct		= inet6_sock_destruct;
 	sk->sk_family		= PF_INET6;
 	sk->sk_protocol		= protocol;
 
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 1805cc5f7418..70e10b8cc648 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -54,6 +54,19 @@
 #include <trace/events/skb.h>
 #include "udp_impl.h"
 
+static void udpv6_destruct_sock(struct sock *sk)
+{
+	udp_destruct_common(sk);
+	inet6_sock_destruct(sk);
+}
+
+int udpv6_init_sock(struct sock *sk)
+{
+	skb_queue_head_init(&udp_sk(sk)->reader_queue);
+	sk->sk_destruct = udpv6_destruct_sock;
+	return 0;
+}
+
 static u32 udp6_ehashfn(const struct net *net,
 			const struct in6_addr *laddr,
 			const u16 lport,
@@ -1700,7 +1713,7 @@ struct proto udpv6_prot = {
 	.connect		= ip6_datagram_connect,
 	.disconnect		= udp_disconnect,
 	.ioctl			= udp_ioctl,
-	.init			= udp_init_sock,
+	.init			= udpv6_init_sock,
 	.destroy		= udpv6_destroy_sock,
 	.setsockopt		= udpv6_setsockopt,
 	.getsockopt		= udpv6_getsockopt,
diff --git a/net/ipv6/udp_impl.h b/net/ipv6/udp_impl.h
index b2fcc46c1630..e49776819441 100644
--- a/net/ipv6/udp_impl.h
+++ b/net/ipv6/udp_impl.h
@@ -12,6 +12,7 @@ int __udp6_lib_rcv(struct sk_buff *, struct udp_table *, int);
 int __udp6_lib_err(struct sk_buff *, struct inet6_skb_parm *, u8, u8, int,
 		   __be32, struct udp_table *);
 
+int udpv6_init_sock(struct sock *sk);
 int udp_v6_get_port(struct sock *sk, unsigned short snum);
 void udp_v6_rehash(struct sock *sk);
 
diff --git a/net/ipv6/udplite.c b/net/ipv6/udplite.c
index fbb700d3f437..b6482e04dad0 100644
--- a/net/ipv6/udplite.c
+++ b/net/ipv6/udplite.c
@@ -12,6 +12,13 @@
 #include <linux/proc_fs.h>
 #include "udp_impl.h"
 
+static int udplitev6_sk_init(struct sock *sk)
+{
+	udpv6_init_sock(sk);
+	udp_sk(sk)->pcflag = UDPLITE_BIT;
+	return 0;
+}
+
 static int udplitev6_rcv(struct sk_buff *skb)
 {
 	return __udp6_lib_rcv(skb, &udplite_table, IPPROTO_UDPLITE);
@@ -38,7 +45,7 @@ struct proto udplitev6_prot = {
 	.connect	   = ip6_datagram_connect,
 	.disconnect	   = udp_disconnect,
 	.ioctl		   = udp_ioctl,
-	.init		   = udplite_sk_init,
+	.init		   = udplitev6_sk_init,
 	.destroy	   = udpv6_destroy_sock,
 	.setsockopt	   = udpv6_setsockopt,
 	.getsockopt	   = udpv6_getsockopt,
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 5.10 3/5] inet6: Remove inet6_destroy_sock() in sk->sk_prot->destroy().
  2023-04-04  9:24 [PATCH 5.10 0/5] Backport complete patchset for call inet6_destroy_sock() in IPv6 sk->sk_destruct() Ziyang Xuan
  2023-04-04  9:24 ` [PATCH 5.10 1/5] udp: Call inet6_destroy_sock() in setsockopt(IPV6_ADDRFORM) Ziyang Xuan
  2023-04-04  9:24 ` [PATCH 5.10 2/5] tcp/udp: Call inet6_destroy_sock() in IPv6 sk->sk_destruct() Ziyang Xuan
@ 2023-04-04  9:24 ` Ziyang Xuan
  2023-04-04  9:25 ` [PATCH 5.10 4/5] dccp: Call inet6_destroy_sock() via sk->sk_destruct() Ziyang Xuan
  2023-04-04  9:25 ` [PATCH 5.10 5/5] sctp: " Ziyang Xuan
  4 siblings, 0 replies; 10+ messages in thread
From: Ziyang Xuan @ 2023-04-04  9:24 UTC (permalink / raw)
  To: gregkh, stable, davem, kuznet, yoshfuji, kuba, kuniyu; +Cc: netdev

From: Kuniyuki Iwashima <kuniyu@amazon.com>

commit b5fc29233d28be7a3322848ebe73ac327559cdb9 upstream.

After commit d38afeec26ed ("tcp/udp: Call inet6_destroy_sock()
in IPv6 sk->sk_destruct()."), we call inet6_destroy_sock() in
sk->sk_destruct() by setting inet6_sock_destruct() to it to make
sure we do not leak inet6-specific resources.

Now we can remove unnecessary inet6_destroy_sock() calls in
sk->sk_prot->destroy().

DCCP and SCTP have their own sk->sk_destruct() function, so we
change them separately in the following patches.

Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
Reviewed-by: Matthieu Baerts <matthieu.baerts@tessares.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Ziyang Xuan <william.xuanziyang@huawei.com>
---
 net/ipv6/ping.c      | 6 ------
 net/ipv6/raw.c       | 2 --
 net/ipv6/tcp_ipv6.c  | 8 +-------
 net/ipv6/udp.c       | 2 --
 net/l2tp/l2tp_ip6.c  | 2 --
 net/mptcp/protocol.c | 7 -------
 6 files changed, 1 insertion(+), 26 deletions(-)

diff --git a/net/ipv6/ping.c b/net/ipv6/ping.c
index 135e3a060caa..6ac88fe24a8e 100644
--- a/net/ipv6/ping.c
+++ b/net/ipv6/ping.c
@@ -22,11 +22,6 @@
 #include <linux/proc_fs.h>
 #include <net/ping.h>
 
-static void ping_v6_destroy(struct sock *sk)
-{
-	inet6_destroy_sock(sk);
-}
-
 /* Compatibility glue so we can support IPv6 when it's compiled as a module */
 static int dummy_ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len,
 				 int *addr_len)
@@ -171,7 +166,6 @@ struct proto pingv6_prot = {
 	.owner =	THIS_MODULE,
 	.init =		ping_init_sock,
 	.close =	ping_close,
-	.destroy =	ping_v6_destroy,
 	.connect =	ip6_datagram_connect_v6_only,
 	.disconnect =	__udp_disconnect,
 	.setsockopt =	ipv6_setsockopt,
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index 110254f44a46..69f0f9c05d02 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -1211,8 +1211,6 @@ static void raw6_destroy(struct sock *sk)
 	lock_sock(sk);
 	ip6_flush_pending_frames(sk);
 	release_sock(sk);
-
-	inet6_destroy_sock(sk);
 }
 
 static int rawv6_init_sk(struct sock *sk)
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index e4ae5362cb51..2347740d3cc7 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -1936,12 +1936,6 @@ static int tcp_v6_init_sock(struct sock *sk)
 	return 0;
 }
 
-static void tcp_v6_destroy_sock(struct sock *sk)
-{
-	tcp_v4_destroy_sock(sk);
-	inet6_destroy_sock(sk);
-}
-
 #ifdef CONFIG_PROC_FS
 /* Proc filesystem TCPv6 sock list dumping. */
 static void get_openreq6(struct seq_file *seq,
@@ -2134,7 +2128,7 @@ struct proto tcpv6_prot = {
 	.accept			= inet_csk_accept,
 	.ioctl			= tcp_ioctl,
 	.init			= tcp_v6_init_sock,
-	.destroy		= tcp_v6_destroy_sock,
+	.destroy		= tcp_v4_destroy_sock,
 	.shutdown		= tcp_shutdown,
 	.setsockopt		= tcp_setsockopt,
 	.getsockopt		= tcp_getsockopt,
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 70e10b8cc648..b94b89b6e70c 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -1628,8 +1628,6 @@ void udpv6_destroy_sock(struct sock *sk)
 			udp_encap_disable();
 		}
 	}
-
-	inet6_destroy_sock(sk);
 }
 
 /*
diff --git a/net/l2tp/l2tp_ip6.c b/net/l2tp/l2tp_ip6.c
index d54dbd01d86f..382124d6f764 100644
--- a/net/l2tp/l2tp_ip6.c
+++ b/net/l2tp/l2tp_ip6.c
@@ -255,8 +255,6 @@ static void l2tp_ip6_destroy_sock(struct sock *sk)
 
 	if (tunnel)
 		l2tp_tunnel_delete(tunnel);
-
-	inet6_destroy_sock(sk);
 }
 
 static int l2tp_ip6_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len)
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index e61c85873ea2..72d944e6a641 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -2863,12 +2863,6 @@ static const struct proto_ops mptcp_v6_stream_ops = {
 
 static struct proto mptcp_v6_prot;
 
-static void mptcp_v6_destroy(struct sock *sk)
-{
-	mptcp_destroy(sk);
-	inet6_destroy_sock(sk);
-}
-
 static struct inet_protosw mptcp_v6_protosw = {
 	.type		= SOCK_STREAM,
 	.protocol	= IPPROTO_MPTCP,
@@ -2884,7 +2878,6 @@ int __init mptcp_proto_v6_init(void)
 	mptcp_v6_prot = mptcp_prot;
 	strcpy(mptcp_v6_prot.name, "MPTCPv6");
 	mptcp_v6_prot.slab = NULL;
-	mptcp_v6_prot.destroy = mptcp_v6_destroy;
 	mptcp_v6_prot.obj_size = sizeof(struct mptcp6_sock);
 
 	err = proto_register(&mptcp_v6_prot, 1);
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 5.10 4/5] dccp: Call inet6_destroy_sock() via sk->sk_destruct().
  2023-04-04  9:24 [PATCH 5.10 0/5] Backport complete patchset for call inet6_destroy_sock() in IPv6 sk->sk_destruct() Ziyang Xuan
                   ` (2 preceding siblings ...)
  2023-04-04  9:24 ` [PATCH 5.10 3/5] inet6: Remove inet6_destroy_sock() in sk->sk_prot->destroy() Ziyang Xuan
@ 2023-04-04  9:25 ` Ziyang Xuan
  2023-04-04  9:25 ` [PATCH 5.10 5/5] sctp: " Ziyang Xuan
  4 siblings, 0 replies; 10+ messages in thread
From: Ziyang Xuan @ 2023-04-04  9:25 UTC (permalink / raw)
  To: gregkh, stable, davem, kuznet, yoshfuji, kuba, kuniyu; +Cc: netdev

From: Kuniyuki Iwashima <kuniyu@amazon.com>

commit 1651951ebea54970e0bda60c638fc2eee7a6218f upstream.

After commit d38afeec26ed ("tcp/udp: Call inet6_destroy_sock()
in IPv6 sk->sk_destruct()."), we call inet6_destroy_sock() in
sk->sk_destruct() by setting inet6_sock_destruct() to it to make
sure we do not leak inet6-specific resources.

DCCP sets its own sk->sk_destruct() in the dccp_init_sock(), and
DCCPv6 socket shares it by calling the same init function via
dccp_v6_init_sock().

To call inet6_sock_destruct() from DCCPv6 sk->sk_destruct(), we
export it and set dccp_v6_sk_destruct() in the init function.

Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Ziyang Xuan <william.xuanziyang@huawei.com>
---
 net/dccp/dccp.h     |  1 +
 net/dccp/ipv6.c     | 15 ++++++++-------
 net/dccp/proto.c    |  8 +++++++-
 net/ipv6/af_inet6.c |  1 +
 4 files changed, 17 insertions(+), 8 deletions(-)

diff --git a/net/dccp/dccp.h b/net/dccp/dccp.h
index 5183e627468d..0218eb169891 100644
--- a/net/dccp/dccp.h
+++ b/net/dccp/dccp.h
@@ -283,6 +283,7 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
 int dccp_rcv_established(struct sock *sk, struct sk_buff *skb,
 			 const struct dccp_hdr *dh, const unsigned int len);
 
+void dccp_destruct_common(struct sock *sk);
 int dccp_init_sock(struct sock *sk, const __u8 ctl_sock_initialized);
 void dccp_destroy_sock(struct sock *sk);
 
diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c
index c563f9b325d0..64e91783860d 100644
--- a/net/dccp/ipv6.c
+++ b/net/dccp/ipv6.c
@@ -992,6 +992,12 @@ static const struct inet_connection_sock_af_ops dccp_ipv6_mapped = {
 	.sockaddr_len	   = sizeof(struct sockaddr_in6),
 };
 
+static void dccp_v6_sk_destruct(struct sock *sk)
+{
+	dccp_destruct_common(sk);
+	inet6_sock_destruct(sk);
+}
+
 /* NOTE: A lot of things set to zero explicitly by call to
  *       sk_alloc() so need not be done here.
  */
@@ -1004,17 +1010,12 @@ static int dccp_v6_init_sock(struct sock *sk)
 		if (unlikely(!dccp_v6_ctl_sock_initialized))
 			dccp_v6_ctl_sock_initialized = 1;
 		inet_csk(sk)->icsk_af_ops = &dccp_ipv6_af_ops;
+		sk->sk_destruct = dccp_v6_sk_destruct;
 	}
 
 	return err;
 }
 
-static void dccp_v6_destroy_sock(struct sock *sk)
-{
-	dccp_destroy_sock(sk);
-	inet6_destroy_sock(sk);
-}
-
 static struct timewait_sock_ops dccp6_timewait_sock_ops = {
 	.twsk_obj_size	= sizeof(struct dccp6_timewait_sock),
 };
@@ -1037,7 +1038,7 @@ static struct proto dccp_v6_prot = {
 	.accept		   = inet_csk_accept,
 	.get_port	   = inet_csk_get_port,
 	.shutdown	   = dccp_shutdown,
-	.destroy	   = dccp_v6_destroy_sock,
+	.destroy	   = dccp_destroy_sock,
 	.orphan_count	   = &dccp_orphan_count,
 	.max_header	   = MAX_DCCP_HEADER,
 	.obj_size	   = sizeof(struct dccp6_sock),
diff --git a/net/dccp/proto.c b/net/dccp/proto.c
index 65e81e0199b0..e946211758c0 100644
--- a/net/dccp/proto.c
+++ b/net/dccp/proto.c
@@ -171,12 +171,18 @@ const char *dccp_packet_name(const int type)
 
 EXPORT_SYMBOL_GPL(dccp_packet_name);
 
-static void dccp_sk_destruct(struct sock *sk)
+void dccp_destruct_common(struct sock *sk)
 {
 	struct dccp_sock *dp = dccp_sk(sk);
 
 	ccid_hc_tx_delete(dp->dccps_hc_tx_ccid, sk);
 	dp->dccps_hc_tx_ccid = NULL;
+}
+EXPORT_SYMBOL_GPL(dccp_destruct_common);
+
+static void dccp_sk_destruct(struct sock *sk)
+{
+	dccp_destruct_common(sk);
 	inet_sock_destruct(sk);
 }
 
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index 5846e386221f..4247997077bf 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -112,6 +112,7 @@ void inet6_sock_destruct(struct sock *sk)
 	inet6_cleanup_sock(sk);
 	inet_sock_destruct(sk);
 }
+EXPORT_SYMBOL_GPL(inet6_sock_destruct);
 
 static int inet6_create(struct net *net, struct socket *sock, int protocol,
 			int kern)
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 5.10 5/5] sctp: Call inet6_destroy_sock() via sk->sk_destruct().
  2023-04-04  9:24 [PATCH 5.10 0/5] Backport complete patchset for call inet6_destroy_sock() in IPv6 sk->sk_destruct() Ziyang Xuan
                   ` (3 preceding siblings ...)
  2023-04-04  9:25 ` [PATCH 5.10 4/5] dccp: Call inet6_destroy_sock() via sk->sk_destruct() Ziyang Xuan
@ 2023-04-04  9:25 ` Ziyang Xuan
  4 siblings, 0 replies; 10+ messages in thread
From: Ziyang Xuan @ 2023-04-04  9:25 UTC (permalink / raw)
  To: gregkh, stable, davem, kuznet, yoshfuji, kuba, kuniyu; +Cc: netdev

From: Kuniyuki Iwashima <kuniyu@amazon.com>

commit 6431b0f6ff1633ae598667e4cdd93830074a03e8 upstream.

After commit d38afeec26ed ("tcp/udp: Call inet6_destroy_sock()
in IPv6 sk->sk_destruct()."), we call inet6_destroy_sock() in
sk->sk_destruct() by setting inet6_sock_destruct() to it to make
sure we do not leak inet6-specific resources.

SCTP sets its own sk->sk_destruct() in the sctp_init_sock(), and
SCTPv6 socket reuses it as the init function.

To call inet6_sock_destruct() from SCTPv6 sk->sk_destruct(), we
set sctp_v6_destruct_sock() in a new init function.

Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Ziyang Xuan <william.xuanziyang@huawei.com>
---
 net/sctp/socket.c | 29 +++++++++++++++++++++--------
 1 file changed, 21 insertions(+), 8 deletions(-)

diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index e9b4ea3d934f..0f0def3b1082 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -4991,13 +4991,17 @@ static void sctp_destroy_sock(struct sock *sk)
 }
 
 /* Triggered when there are no references on the socket anymore */
-static void sctp_destruct_sock(struct sock *sk)
+static void sctp_destruct_common(struct sock *sk)
 {
 	struct sctp_sock *sp = sctp_sk(sk);
 
 	/* Free up the HMAC transform. */
 	crypto_free_shash(sp->hmac);
+}
 
+static void sctp_destruct_sock(struct sock *sk)
+{
+	sctp_destruct_common(sk);
 	inet_sock_destruct(sk);
 }
 
@@ -9191,7 +9195,7 @@ void sctp_copy_sock(struct sock *newsk, struct sock *sk,
 	sctp_sk(newsk)->reuse = sp->reuse;
 
 	newsk->sk_shutdown = sk->sk_shutdown;
-	newsk->sk_destruct = sctp_destruct_sock;
+	newsk->sk_destruct = sk->sk_destruct;
 	newsk->sk_family = sk->sk_family;
 	newsk->sk_protocol = IPPROTO_SCTP;
 	newsk->sk_backlog_rcv = sk->sk_prot->backlog_rcv;
@@ -9423,11 +9427,20 @@ struct proto sctp_prot = {
 
 #if IS_ENABLED(CONFIG_IPV6)
 
-#include <net/transp_v6.h>
-static void sctp_v6_destroy_sock(struct sock *sk)
+static void sctp_v6_destruct_sock(struct sock *sk)
+{
+	sctp_destruct_common(sk);
+	inet6_sock_destruct(sk);
+}
+
+static int sctp_v6_init_sock(struct sock *sk)
 {
-	sctp_destroy_sock(sk);
-	inet6_destroy_sock(sk);
+	int ret = sctp_init_sock(sk);
+
+	if (!ret)
+		sk->sk_destruct = sctp_v6_destruct_sock;
+
+	return ret;
 }
 
 struct proto sctpv6_prot = {
@@ -9437,8 +9450,8 @@ struct proto sctpv6_prot = {
 	.disconnect	= sctp_disconnect,
 	.accept		= sctp_accept,
 	.ioctl		= sctp_ioctl,
-	.init		= sctp_init_sock,
-	.destroy	= sctp_v6_destroy_sock,
+	.init		= sctp_v6_init_sock,
+	.destroy	= sctp_destroy_sock,
 	.shutdown	= sctp_shutdown,
 	.setsockopt	= sctp_setsockopt,
 	.getsockopt	= sctp_getsockopt,
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH 5.10 1/5] udp: Call inet6_destroy_sock() in setsockopt(IPV6_ADDRFORM).
  2023-04-04  9:24 ` [PATCH 5.10 1/5] udp: Call inet6_destroy_sock() in setsockopt(IPV6_ADDRFORM) Ziyang Xuan
@ 2023-04-18 10:21   ` Greg KH
  2023-04-18 10:21     ` Greg KH
  0 siblings, 1 reply; 10+ messages in thread
From: Greg KH @ 2023-04-18 10:21 UTC (permalink / raw)
  To: Ziyang Xuan; +Cc: stable, davem, kuznet, yoshfuji, kuba, kuniyu, netdev

On Tue, Apr 04, 2023 at 05:24:28PM +0800, Ziyang Xuan wrote:
> From: Kuniyuki Iwashima <kuniyu@amazon.com>
> 
> commit 21985f43376cee092702d6cb963ff97a9d2ede68 upstream.

Why is this only relevant for 5.10.y?  What about 5.15.y?

For obvious reasons, we can not take patches only for older branches as
that would cause people to have regressions when moving to newer kernel
releases.  So can you please fix this up by sending a 5.15.y series, and
this 5.10.y series again, and we can queue them all up at the same time?

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 5.10 1/5] udp: Call inet6_destroy_sock() in setsockopt(IPV6_ADDRFORM).
  2023-04-18 10:21   ` Greg KH
@ 2023-04-18 10:21     ` Greg KH
  2023-04-18 12:53       ` Ziyang Xuan (William)
  0 siblings, 1 reply; 10+ messages in thread
From: Greg KH @ 2023-04-18 10:21 UTC (permalink / raw)
  To: Ziyang Xuan; +Cc: stable, davem, kuznet, yoshfuji, kuba, kuniyu, netdev

On Tue, Apr 18, 2023 at 12:21:21PM +0200, Greg KH wrote:
> On Tue, Apr 04, 2023 at 05:24:28PM +0800, Ziyang Xuan wrote:
> > From: Kuniyuki Iwashima <kuniyu@amazon.com>
> > 
> > commit 21985f43376cee092702d6cb963ff97a9d2ede68 upstream.
> 
> Why is this only relevant for 5.10.y?  What about 5.15.y?
> 
> For obvious reasons, we can not take patches only for older branches as
> that would cause people to have regressions when moving to newer kernel
> releases.  So can you please fix this up by sending a 5.15.y series, and
> this 5.10.y series again, and we can queue them all up at the same time?

Also a 6.1.y series to be complete.

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 5.10 1/5] udp: Call inet6_destroy_sock() in setsockopt(IPV6_ADDRFORM).
  2023-04-18 10:21     ` Greg KH
@ 2023-04-18 12:53       ` Ziyang Xuan (William)
  2023-04-18 12:57         ` Greg KH
  0 siblings, 1 reply; 10+ messages in thread
From: Ziyang Xuan (William) @ 2023-04-18 12:53 UTC (permalink / raw)
  To: Greg KH; +Cc: stable, davem, kuznet, yoshfuji, kuba, kuniyu, netdev

> On Tue, Apr 18, 2023 at 12:21:21PM +0200, Greg KH wrote:
>> On Tue, Apr 04, 2023 at 05:24:28PM +0800, Ziyang Xuan wrote:
>>> From: Kuniyuki Iwashima <kuniyu@amazon.com>
>>>
>>> commit 21985f43376cee092702d6cb963ff97a9d2ede68 upstream.
>>
>> Why is this only relevant for 5.10.y?  What about 5.15.y?
>>
>> For obvious reasons, we can not take patches only for older branches as
>> that would cause people to have regressions when moving to newer kernel
>> releases.  So can you please fix this up by sending a 5.15.y series, and
>> this 5.10.y series again, and we can queue them all up at the same time?
> 
> Also a 6.1.y series to be complete.
> 
4.14.y, 4.19.y, 5.4.y, 5.10.y, 5.15.y and 6.1.y are all involved.
Can I send series for them all together?

William Xuan

> thanks,
> 
> greg k-h
> .
> 

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 5.10 1/5] udp: Call inet6_destroy_sock() in setsockopt(IPV6_ADDRFORM).
  2023-04-18 12:53       ` Ziyang Xuan (William)
@ 2023-04-18 12:57         ` Greg KH
  0 siblings, 0 replies; 10+ messages in thread
From: Greg KH @ 2023-04-18 12:57 UTC (permalink / raw)
  To: Ziyang Xuan (William)
  Cc: stable, davem, kuznet, yoshfuji, kuba, kuniyu, netdev

On Tue, Apr 18, 2023 at 08:53:32PM +0800, Ziyang Xuan (William) wrote:
> > On Tue, Apr 18, 2023 at 12:21:21PM +0200, Greg KH wrote:
> >> On Tue, Apr 04, 2023 at 05:24:28PM +0800, Ziyang Xuan wrote:
> >>> From: Kuniyuki Iwashima <kuniyu@amazon.com>
> >>>
> >>> commit 21985f43376cee092702d6cb963ff97a9d2ede68 upstream.
> >>
> >> Why is this only relevant for 5.10.y?  What about 5.15.y?
> >>
> >> For obvious reasons, we can not take patches only for older branches as
> >> that would cause people to have regressions when moving to newer kernel
> >> releases.  So can you please fix this up by sending a 5.15.y series, and
> >> this 5.10.y series again, and we can queue them all up at the same time?
> > 
> > Also a 6.1.y series to be complete.
> > 
> 4.14.y, 4.19.y, 5.4.y, 5.10.y, 5.15.y and 6.1.y are all involved.
> Can I send series for them all together?

Yes please, as 5 different patch series.

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2023-04-18 12:57 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-04-04  9:24 [PATCH 5.10 0/5] Backport complete patchset for call inet6_destroy_sock() in IPv6 sk->sk_destruct() Ziyang Xuan
2023-04-04  9:24 ` [PATCH 5.10 1/5] udp: Call inet6_destroy_sock() in setsockopt(IPV6_ADDRFORM) Ziyang Xuan
2023-04-18 10:21   ` Greg KH
2023-04-18 10:21     ` Greg KH
2023-04-18 12:53       ` Ziyang Xuan (William)
2023-04-18 12:57         ` Greg KH
2023-04-04  9:24 ` [PATCH 5.10 2/5] tcp/udp: Call inet6_destroy_sock() in IPv6 sk->sk_destruct() Ziyang Xuan
2023-04-04  9:24 ` [PATCH 5.10 3/5] inet6: Remove inet6_destroy_sock() in sk->sk_prot->destroy() Ziyang Xuan
2023-04-04  9:25 ` [PATCH 5.10 4/5] dccp: Call inet6_destroy_sock() via sk->sk_destruct() Ziyang Xuan
2023-04-04  9:25 ` [PATCH 5.10 5/5] sctp: " Ziyang Xuan

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.