--- /dev/null
+From stable+bounces-168392-greg=kroah.com@vger.kernel.org Tue Aug 12 20:44:38 2025
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 12 Aug 2025 14:40:15 -0400
+Subject: net: Add net_passive_inc() and net_passive_dec().
+To: stable@vger.kernel.org
+Cc: Kuniyuki Iwashima <kuniyu@amazon.com>, Eric Dumazet <edumazet@google.com>, Jakub Kicinski <kuba@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20250812184017.2025429-1-sashal@kernel.org>
+
+From: Kuniyuki Iwashima <kuniyu@amazon.com>
+
+[ Upstream commit e57a6320215c3967f51ab0edeff87db2095440e4 ]
+
+net_drop_ns() is NULL when CONFIG_NET_NS is disabled.
+
+The next patch introduces a function that increments
+and decrements net->passive.
+
+As a prep, let's rename and export net_free() to
+net_passive_dec() and add net_passive_inc().
+
+Suggested-by: Eric Dumazet <edumazet@google.com>
+Link: https://lore.kernel.org/netdev/CANn89i+oUCt2VGvrbrweniTendZFEh+nwS=uonc004-aPkWy-Q@mail.gmail.com/
+Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Link: https://patch.msgid.link/20250217191129.19967-2-kuniyu@amazon.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 59b33fab4ca4 ("smb: client: fix netns refcount leak after net_passive changes")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/net/net_namespace.h | 16 ++++++++++++++++
+ net/core/net_namespace.c | 8 ++++----
+ 2 files changed, 20 insertions(+), 4 deletions(-)
+
+--- a/include/net/net_namespace.h
++++ b/include/net/net_namespace.h
+@@ -293,6 +293,7 @@ static inline int check_net(const struct
+ }
+
+ void net_drop_ns(void *);
++void net_passive_dec(struct net *net);
+
+ #else
+
+@@ -322,8 +323,23 @@ static inline int check_net(const struct
+ }
+
+ #define net_drop_ns NULL
++
++static inline void net_passive_dec(struct net *net)
++{
++ refcount_dec(&net->passive);
++}
+ #endif
+
++static inline void net_passive_inc(struct net *net)
++{
++ refcount_inc(&net->passive);
++}
++
++/* Returns true if the netns initialization is completed successfully */
++static inline bool net_initialized(const struct net *net)
++{
++ return READ_ONCE(net->list.next);
++}
+
+ static inline void __netns_tracker_alloc(struct net *net,
+ netns_tracker *tracker,
+--- a/net/core/net_namespace.c
++++ b/net/core/net_namespace.c
+@@ -467,7 +467,7 @@ static void net_complete_free(void)
+
+ }
+
+-static void net_free(struct net *net)
++void net_passive_dec(struct net *net)
+ {
+ if (refcount_dec_and_test(&net->passive)) {
+ kfree(rcu_access_pointer(net->gen));
+@@ -485,7 +485,7 @@ void net_drop_ns(void *p)
+ struct net *net = (struct net *)p;
+
+ if (net)
+- net_free(net);
++ net_passive_dec(net);
+ }
+
+ struct net *copy_net_ns(unsigned long flags,
+@@ -527,7 +527,7 @@ put_userns:
+ key_remove_domain(net->key_domain);
+ #endif
+ put_user_ns(user_ns);
+- net_free(net);
++ net_passive_dec(net);
+ dec_ucounts:
+ dec_net_namespaces(ucounts);
+ return ERR_PTR(rv);
+@@ -672,7 +672,7 @@ static void cleanup_net(struct work_stru
+ key_remove_domain(net->key_domain);
+ #endif
+ put_user_ns(net->user_ns);
+- net_free(net);
++ net_passive_dec(net);
+ }
+ }
+
--- /dev/null
+From stable+bounces-168393-greg=kroah.com@vger.kernel.org Tue Aug 12 20:40:41 2025
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 12 Aug 2025 14:40:16 -0400
+Subject: net: better track kernel sockets lifetime
+To: stable@vger.kernel.org
+Cc: Eric Dumazet <edumazet@google.com>, syzbot+30a19e01a97420719891@syzkaller.appspotmail.com, Kuniyuki Iwashima <kuniyu@amazon.com>, Jakub Kicinski <kuba@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20250812184017.2025429-2-sashal@kernel.org>
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 5c70eb5c593d64d93b178905da215a9fd288a4b5 ]
+
+While kernel sockets are dismantled during pernet_operations->exit(),
+their freeing can be delayed by any tx packets still held in qdisc
+or device queues, due to skb_set_owner_w() prior calls.
+
+This then trigger the following warning from ref_tracker_dir_exit() [1]
+
+To fix this, make sure that kernel sockets own a reference on net->passive.
+
+Add sk_net_refcnt_upgrade() helper, used whenever a kernel socket
+is converted to a refcounted one.
+
+[1]
+
+[ 136.263918][ T35] ref_tracker: net notrefcnt@ffff8880638f01e0 has 1/2 users at
+[ 136.263918][ T35] sk_alloc+0x2b3/0x370
+[ 136.263918][ T35] inet6_create+0x6ce/0x10f0
+[ 136.263918][ T35] __sock_create+0x4c0/0xa30
+[ 136.263918][ T35] inet_ctl_sock_create+0xc2/0x250
+[ 136.263918][ T35] igmp6_net_init+0x39/0x390
+[ 136.263918][ T35] ops_init+0x31e/0x590
+[ 136.263918][ T35] setup_net+0x287/0x9e0
+[ 136.263918][ T35] copy_net_ns+0x33f/0x570
+[ 136.263918][ T35] create_new_namespaces+0x425/0x7b0
+[ 136.263918][ T35] unshare_nsproxy_namespaces+0x124/0x180
+[ 136.263918][ T35] ksys_unshare+0x57d/0xa70
+[ 136.263918][ T35] __x64_sys_unshare+0x38/0x40
+[ 136.263918][ T35] do_syscall_64+0xf3/0x230
+[ 136.263918][ T35] entry_SYSCALL_64_after_hwframe+0x77/0x7f
+[ 136.263918][ T35]
+[ 136.343488][ T35] ref_tracker: net notrefcnt@ffff8880638f01e0 has 1/2 users at
+[ 136.343488][ T35] sk_alloc+0x2b3/0x370
+[ 136.343488][ T35] inet6_create+0x6ce/0x10f0
+[ 136.343488][ T35] __sock_create+0x4c0/0xa30
+[ 136.343488][ T35] inet_ctl_sock_create+0xc2/0x250
+[ 136.343488][ T35] ndisc_net_init+0xa7/0x2b0
+[ 136.343488][ T35] ops_init+0x31e/0x590
+[ 136.343488][ T35] setup_net+0x287/0x9e0
+[ 136.343488][ T35] copy_net_ns+0x33f/0x570
+[ 136.343488][ T35] create_new_namespaces+0x425/0x7b0
+[ 136.343488][ T35] unshare_nsproxy_namespaces+0x124/0x180
+[ 136.343488][ T35] ksys_unshare+0x57d/0xa70
+[ 136.343488][ T35] __x64_sys_unshare+0x38/0x40
+[ 136.343488][ T35] do_syscall_64+0xf3/0x230
+[ 136.343488][ T35] entry_SYSCALL_64_after_hwframe+0x77/0x7f
+
+Fixes: 0cafd77dcd03 ("net: add a refcount tracker for kernel sockets")
+Reported-by: syzbot+30a19e01a97420719891@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/netdev/67b72aeb.050a0220.14d86d.0283.GAE@google.com/T/#u
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Link: https://patch.msgid.link/20250220131854.4048077-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/net/sock.h | 1 +
+ net/core/sock.c | 27 ++++++++++++++++++++++-----
+ net/mptcp/subflow.c | 5 +----
+ net/netlink/af_netlink.c | 10 ----------
+ net/rds/tcp.c | 8 ++------
+ net/smc/af_smc.c | 5 +----
+ net/sunrpc/svcsock.c | 5 +----
+ net/sunrpc/xprtsock.c | 8 ++------
+ 8 files changed, 30 insertions(+), 39 deletions(-)
+
+--- a/include/net/sock.h
++++ b/include/net/sock.h
+@@ -1859,6 +1859,7 @@ static inline bool sock_allow_reclassifi
+ struct sock *sk_alloc(struct net *net, int family, gfp_t priority,
+ struct proto *prot, int kern);
+ void sk_free(struct sock *sk);
++void sk_net_refcnt_upgrade(struct sock *sk);
+ void sk_destruct(struct sock *sk);
+ struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority);
+ void sk_free_unlock_clone(struct sock *sk);
+--- a/net/core/sock.c
++++ b/net/core/sock.c
+@@ -2159,6 +2159,7 @@ struct sock *sk_alloc(struct net *net, i
+ get_net_track(net, &sk->ns_tracker, priority);
+ sock_inuse_add(net, 1);
+ } else {
++ net_passive_inc(net);
+ __netns_tracker_alloc(net, &sk->ns_tracker,
+ false, priority);
+ }
+@@ -2183,6 +2184,7 @@ EXPORT_SYMBOL(sk_alloc);
+ static void __sk_destruct(struct rcu_head *head)
+ {
+ struct sock *sk = container_of(head, struct sock, sk_rcu);
++ struct net *net = sock_net(sk);
+ struct sk_filter *filter;
+
+ if (sk->sk_destruct)
+@@ -2214,14 +2216,28 @@ static void __sk_destruct(struct rcu_hea
+ put_cred(sk->sk_peer_cred);
+ put_pid(sk->sk_peer_pid);
+
+- if (likely(sk->sk_net_refcnt))
+- put_net_track(sock_net(sk), &sk->ns_tracker);
+- else
+- __netns_tracker_free(sock_net(sk), &sk->ns_tracker, false);
+-
++ if (likely(sk->sk_net_refcnt)) {
++ put_net_track(net, &sk->ns_tracker);
++ } else {
++ __netns_tracker_free(net, &sk->ns_tracker, false);
++ net_passive_dec(net);
++ }
+ sk_prot_free(sk->sk_prot_creator, sk);
+ }
+
++void sk_net_refcnt_upgrade(struct sock *sk)
++{
++ struct net *net = sock_net(sk);
++
++ WARN_ON_ONCE(sk->sk_net_refcnt);
++ __netns_tracker_free(net, &sk->ns_tracker, false);
++ net_passive_dec(net);
++ sk->sk_net_refcnt = 1;
++ get_net_track(net, &sk->ns_tracker, GFP_KERNEL);
++ sock_inuse_add(net, 1);
++}
++EXPORT_SYMBOL_GPL(sk_net_refcnt_upgrade);
++
+ void sk_destruct(struct sock *sk)
+ {
+ bool use_call_rcu = sock_flag(sk, SOCK_RCU_FREE);
+@@ -2313,6 +2329,7 @@ struct sock *sk_clone_lock(const struct
+ * is not properly dismantling its kernel sockets at netns
+ * destroy time.
+ */
++ net_passive_inc(sock_net(newsk));
+ __netns_tracker_alloc(sock_net(newsk), &newsk->ns_tracker,
+ false, priority);
+ }
+--- a/net/mptcp/subflow.c
++++ b/net/mptcp/subflow.c
+@@ -1715,10 +1715,7 @@ int mptcp_subflow_create_socket(struct s
+ * needs it.
+ * Update ns_tracker to current stack trace and refcounted tracker.
+ */
+- __netns_tracker_free(net, &sf->sk->ns_tracker, false);
+- sf->sk->sk_net_refcnt = 1;
+- get_net_track(net, &sf->sk->ns_tracker, GFP_KERNEL);
+- sock_inuse_add(net, 1);
++ sk_net_refcnt_upgrade(sf->sk);
+ err = tcp_set_ulp(sf->sk, "mptcp");
+
+ release_ssk:
+--- a/net/netlink/af_netlink.c
++++ b/net/netlink/af_netlink.c
+@@ -798,16 +798,6 @@ static int netlink_release(struct socket
+
+ sock_prot_inuse_add(sock_net(sk), &netlink_proto, -1);
+
+- /* Because struct net might disappear soon, do not keep a pointer. */
+- if (!sk->sk_net_refcnt && sock_net(sk) != &init_net) {
+- __netns_tracker_free(sock_net(sk), &sk->ns_tracker, false);
+- /* Because of deferred_put_nlk_sk and use of work queue,
+- * it is possible netns will be freed before this socket.
+- */
+- sock_net_set(sk, &init_net);
+- __netns_tracker_alloc(&init_net, &sk->ns_tracker,
+- false, GFP_KERNEL);
+- }
+ call_rcu(&nlk->rcu, deferred_put_nlk_sk);
+ return 0;
+ }
+--- a/net/rds/tcp.c
++++ b/net/rds/tcp.c
+@@ -503,12 +503,8 @@ bool rds_tcp_tune(struct socket *sock)
+ release_sock(sk);
+ return false;
+ }
+- /* Update ns_tracker to current stack trace and refcounted tracker */
+- __netns_tracker_free(net, &sk->ns_tracker, false);
+-
+- sk->sk_net_refcnt = 1;
+- netns_tracker_alloc(net, &sk->ns_tracker, GFP_KERNEL);
+- sock_inuse_add(net, 1);
++ sk_net_refcnt_upgrade(sk);
++ put_net(net);
+ }
+ rtn = net_generic(net, rds_tcp_netid);
+ if (rtn->sndbuf_size > 0) {
+--- a/net/smc/af_smc.c
++++ b/net/smc/af_smc.c
+@@ -3343,10 +3343,7 @@ int smc_create_clcsk(struct net *net, st
+ * which need net ref.
+ */
+ sk = smc->clcsock->sk;
+- __netns_tracker_free(net, &sk->ns_tracker, false);
+- sk->sk_net_refcnt = 1;
+- get_net_track(net, &sk->ns_tracker, GFP_KERNEL);
+- sock_inuse_add(net, 1);
++ sk_net_refcnt_upgrade(sk);
+ return 0;
+ }
+
+--- a/net/sunrpc/svcsock.c
++++ b/net/sunrpc/svcsock.c
+@@ -1579,10 +1579,7 @@ static struct svc_xprt *svc_create_socke
+ newlen = error;
+
+ if (protocol == IPPROTO_TCP) {
+- __netns_tracker_free(net, &sock->sk->ns_tracker, false);
+- sock->sk->sk_net_refcnt = 1;
+- get_net_track(net, &sock->sk->ns_tracker, GFP_KERNEL);
+- sock_inuse_add(net, 1);
++ sk_net_refcnt_upgrade(sock->sk);
+ if ((error = kernel_listen(sock, 64)) < 0)
+ goto bummer;
+ }
+--- a/net/sunrpc/xprtsock.c
++++ b/net/sunrpc/xprtsock.c
+@@ -1941,12 +1941,8 @@ static struct socket *xs_create_sock(str
+ goto out;
+ }
+
+- if (protocol == IPPROTO_TCP) {
+- __netns_tracker_free(xprt->xprt_net, &sock->sk->ns_tracker, false);
+- sock->sk->sk_net_refcnt = 1;
+- get_net_track(xprt->xprt_net, &sock->sk->ns_tracker, GFP_KERNEL);
+- sock_inuse_add(xprt->xprt_net, 1);
+- }
++ if (protocol == IPPROTO_TCP)
++ sk_net_refcnt_upgrade(sock->sk);
+
+ filp = sock_alloc_file(sock, O_NONBLOCK, NULL);
+ if (IS_ERR(filp))
--- /dev/null
+From stable+bounces-168395-greg=kroah.com@vger.kernel.org Tue Aug 12 20:40:46 2025
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 12 Aug 2025 14:40:17 -0400
+Subject: smb: client: fix netns refcount leak after net_passive changes
+To: stable@vger.kernel.org
+Cc: Wang Zhaolong <wangzhaolong@huaweicloud.com>, Kuniyuki Iwashima <kuniyu@google.com>, Enzo Matsumiya <ematsumiya@suse.de>, Steve French <stfrench@microsoft.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20250812184017.2025429-3-sashal@kernel.org>
+
+From: Wang Zhaolong <wangzhaolong@huaweicloud.com>
+
+[ Upstream commit 59b33fab4ca4d7dacc03367082777627e05d0323 ]
+
+After commit 5c70eb5c593d ("net: better track kernel sockets lifetime"),
+kernel sockets now use net_passive reference counting. However, commit
+95d2b9f693ff ("Revert "smb: client: fix TCP timers deadlock after rmmod"")
+restored the manual socket refcount manipulation without adapting to this
+new mechanism, causing a memory leak.
+
+The issue can be reproduced by[1]:
+1. Creating a network namespace
+2. Mounting and Unmounting CIFS within the namespace
+3. Deleting the namespace
+
+Some memory leaks may appear after a period of time following step 3.
+
+unreferenced object 0xffff9951419f6b00 (size 256):
+ comm "ip", pid 447, jiffies 4294692389 (age 14.730s)
+ hex dump (first 32 bytes):
+ 1b 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 00 00 00 00 00 00 00 00 80 77 c2 44 51 99 ff ff .........w.DQ...
+ backtrace:
+ __kmem_cache_alloc_node+0x30e/0x3d0
+ __kmalloc+0x52/0x120
+ net_alloc_generic+0x1d/0x30
+ copy_net_ns+0x86/0x200
+ create_new_namespaces+0x117/0x300
+ unshare_nsproxy_namespaces+0x60/0xa0
+ ksys_unshare+0x148/0x360
+ __x64_sys_unshare+0x12/0x20
+ do_syscall_64+0x59/0x110
+ entry_SYSCALL_64_after_hwframe+0x78/0xe2
+...
+unreferenced object 0xffff9951442e7500 (size 32):
+ comm "mount.cifs", pid 475, jiffies 4294693782 (age 13.343s)
+ hex dump (first 32 bytes):
+ 40 c5 38 46 51 99 ff ff 18 01 96 42 51 99 ff ff @.8FQ......BQ...
+ 01 00 00 00 6f 00 c5 07 6f 00 d8 07 00 00 00 00 ....o...o.......
+ backtrace:
+ __kmem_cache_alloc_node+0x30e/0x3d0
+ kmalloc_trace+0x2a/0x90
+ ref_tracker_alloc+0x8e/0x1d0
+ sk_alloc+0x18c/0x1c0
+ inet_create+0xf1/0x370
+ __sock_create+0xd7/0x1e0
+ generic_ip_connect+0x1d4/0x5a0 [cifs]
+ cifs_get_tcp_session+0x5d0/0x8a0 [cifs]
+ cifs_mount_get_session+0x47/0x1b0 [cifs]
+ dfs_mount_share+0xfa/0xa10 [cifs]
+ cifs_mount+0x68/0x2b0 [cifs]
+ cifs_smb3_do_mount+0x10b/0x760 [cifs]
+ smb3_get_tree+0x112/0x2e0 [cifs]
+ vfs_get_tree+0x29/0xf0
+ path_mount+0x2d4/0xa00
+ __se_sys_mount+0x165/0x1d0
+
+Root cause:
+When creating kernel sockets, sk_alloc() calls net_passive_inc() for
+sockets with sk_net_refcnt=0. The CIFS code manually converts kernel
+sockets to user sockets by setting sk_net_refcnt=1, but doesn't call
+the corresponding net_passive_dec(). This creates an imbalance in the
+net_passive counter, which prevents the network namespace from being
+destroyed when its last user reference is dropped. As a result, the
+entire namespace and all its associated resources remain allocated.
+
+Timeline of patches leading to this issue:
+- commit ef7134c7fc48 ("smb: client: Fix use-after-free of network
+ namespace.") in v6.12 fixed the original netns UAF by manually
+ managing socket refcounts
+- commit e9f2517a3e18 ("smb: client: fix TCP timers deadlock after
+ rmmod") in v6.13 attempted to use kernel sockets but introduced
+ TCP timer issues
+- commit 5c70eb5c593d ("net: better track kernel sockets lifetime")
+ in v6.14-rc5 introduced the net_passive mechanism with
+ sk_net_refcnt_upgrade() for proper socket conversion
+- commit 95d2b9f693ff ("Revert "smb: client: fix TCP timers deadlock
+ after rmmod"") in v6.15-rc3 reverted to manual refcount management
+ without adapting to the new net_passive changes
+
+Fix this by using sk_net_refcnt_upgrade() which properly handles the
+net_passive counter when converting kernel sockets to user sockets.
+
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=220343 [1]
+Fixes: 95d2b9f693ff ("Revert "smb: client: fix TCP timers deadlock after rmmod"")
+Cc: stable@vger.kernel.org
+Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
+Reviewed-by: Enzo Matsumiya <ematsumiya@suse.de>
+Signed-off-by: Wang Zhaolong <wangzhaolong@huaweicloud.com>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/smb/client/connect.c | 9 +++------
+ 1 file changed, 3 insertions(+), 6 deletions(-)
+
+--- a/fs/smb/client/connect.c
++++ b/fs/smb/client/connect.c
+@@ -3162,18 +3162,15 @@ generic_ip_connect(struct TCP_Server_Inf
+ struct net *net = cifs_net_ns(server);
+ struct sock *sk;
+
+- rc = __sock_create(net, sfamily, SOCK_STREAM,
+- IPPROTO_TCP, &server->ssocket, 1);
++ rc = sock_create_kern(net, sfamily, SOCK_STREAM,
++ IPPROTO_TCP, &server->ssocket);
+ if (rc < 0) {
+ cifs_server_dbg(VFS, "Error %d creating socket\n", rc);
+ return rc;
+ }
+
+ sk = server->ssocket->sk;
+- __netns_tracker_free(net, &sk->ns_tracker, false);
+- sk->sk_net_refcnt = 1;
+- get_net_track(net, &sk->ns_tracker, GFP_KERNEL);
+- sock_inuse_add(net, 1);
++ sk_net_refcnt_upgrade(sk);
+
+ /* BB other socket options to set KEEPALIVE, NODELAY? */
+ cifs_dbg(FYI, "Socket created\n");