All of lore.kernel.org
 help / color / mirror / Atom feed
From: Chuyf26 <Chuyf26@linux.alibaba.com>
To: pabeni@redhat.com
Cc: alibuda@linux.alibaba.com, dust.li@linux.ibm.com,
	sidraya@linux.ibm.com, mjambigi@linux.ibm.com,
	tonylu@linux.alibaba.com, guwen@linux.alibaba.com,
	netdev@vger.kernel.org, linux-rdma@vger.kernel.org,
	linux-s390@vger.kernel.org
Subject: [PATCH v3] net/smc: release the internal TCP sock on IPPROTO_SMC socket creation failure
Date: Fri, 21 Aug 2026 15:38:23 +0800	[thread overview]
Message-ID: <178729790329.223882.15209084993558811810@linux.alibaba.com> (raw)
In-Reply-To: <20260820111229.153086-1-pabeni@redhat.com>

IPPROTO_SMC sockets create an internal TCP sock ("clcsock") from the
proto->init hook. When socket creation fails after proto->init has
run - e.g. a cgroup BPF program attached to BPF_CGROUP_INET_SOCK_CREATE
denies the socket - sk_common_release() only invokes sk_prot->destroy
if it is set, but neither smc_inet_prot nor smc_inet6_prot defines it,
and smc_destruct() returns early unless sk_state is SMC_CLOSED. As a
result, every failing socket(AF_INET, SOCK_STREAM, IPPROTO_SMC) call
leaks one tcp_sock, so an unprivileged task able to attach a deny-all
BPF_CGROUP_INET_SOCK_CREATE program to its own cgroup can grow kernel
memory unboundedly.

Add a .destroy hook to both protos that releases the clcsock via
smc_clcsock_release(). smc_sk_init() hashes the sock into the smc
hashinfo before the clcsock is created, and smc_diag dumps walk that
hash dereferencing smc->clcsock without taking clcsock_release_lock,
while sk_common_release() calls .destroy before .unhash. Unhash the
sock before releasing the clcsock, as __smc_release() does, so a
concurrent dump cannot observe the release; the second unhash in
sk_common_release() is a no-op.

Fixes: d25a92ccae6b ("net/smc: Introduce IPPROTO_SMC")
Reported-by: Abaci <abaci@linux.alibaba.com>
Assisted-by: abaci:qwen3.8-max
Signed-off-by: Chuyf26 <Chuyf26@linux.alibaba.com>
---
Changes since v2 (answering the review):
- dropped the smc->clcsock = NULL store: sk_alloc() zeroes the sock
  (__GFP_ZERO / sk_prot_clear_nulls()), so it is already NULL. The
  mutex concern does not apply either: .destroy only runs after
  smc_sk_init() initialized clcsock_release_lock.
- unhash the sock before releasing the clcsock in .destroy so a
  concurrent smc_diag dump cannot observe the release
  (sk_common_release() calls .destroy before .unhash); the second
  unhash is a no-op. Tested on a KASAN+SMC_DIAG kernel: the v2
  version hits a KASAN report in __smc_diag_dump() when a diag dump
  races with failing IPPROTO_SMC socket creation, v3 stays clean
  under the same stress.

 net/smc/smc_inet.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/net/smc/smc_inet.c b/net/smc/smc_inet.c
index a94084b4a498..520b666fdd8f 100644
--- a/net/smc/smc_inet.c
+++ b/net/smc/smc_inet.c
@@ -15,13 +15,16 @@
 
 #include "smc_inet.h"
 #include "smc.h"
+#include "smc_close.h"
 
 static int smc_inet_init_sock(struct sock *sk);
+static void smc_inet_destroy_sock(struct sock *sk);
 
 static struct proto smc_inet_prot = {
 	.name		= "INET_SMC",
 	.owner		= THIS_MODULE,
 	.init		= smc_inet_init_sock,
+	.destroy	= smc_inet_destroy_sock,
 	.hash		= smc_hash_sk,
 	.unhash		= smc_unhash_sk,
 	.release_cb	= smc_release_cb,
@@ -68,6 +71,7 @@ static struct proto smc_inet6_prot = {
 	.name		= "INET6_SMC",
 	.owner		= THIS_MODULE,
 	.init		= smc_inet_init_sock,
+	.destroy	= smc_inet_destroy_sock,
 	.hash		= smc_hash_sk,
 	.unhash		= smc_unhash_sk,
 	.release_cb	= smc_release_cb,
@@ -116,6 +120,18 @@ static int smc_inet_init_sock(struct sock *sk)
 	return smc_create_clcsk(net, sk, sk->sk_family);
 }
 
+static void smc_inet_destroy_sock(struct sock *sk)
+{
+	/* The sock is hashed and smc_diag dumps dereference smc->clcsock
+	 * without clcsock_release_lock, while sk_common_release() calls
+	 * .destroy before .unhash. Unhash first, as __smc_release() does,
+	 * so no dump can observe the clcsock being released; the second
+	 * unhash is a no-op.
+	 */
+	sk->sk_prot->unhash(sk);
+	smc_clcsock_release(smc_sk(sk));
+}
+
 int __init smc_inet_init(void)
 {
 	int rc;
-- 
2.43.5

  reply	other threads:[~2026-08-21  7:40 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20260812071543.C94FD349CD8@smtp.subspace.kernel.org>
2026-08-12 14:44 ` [PATCH] net/smc: release the internal TCP sock on IPPROTO_SMC socket creation failure Sidraya Jayagond
2026-08-13  6:04   ` [PATCH v2] " Chuyf26
2026-08-13  6:14     ` sashiko-bot
2026-08-20 11:12     ` Paolo Abeni
2026-08-21  7:38       ` Chuyf26 [this message]
2026-08-21 23:53         ` [PATCH v3] " Jakub Kicinski
2026-08-22  7:40         ` sashiko-bot
     [not found]   ` <202608130604.67D5j4VU1508130@pps.reinject>
2026-08-13  6:25     ` [PATCH v2] " Sidraya Jayagond
2026-08-12  7:15 [PATCH] " Chuyf26
2026-08-12  7:25 ` sashiko-bot

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=178729790329.223882.15209084993558811810@linux.alibaba.com \
    --to=chuyf26@linux.alibaba.com \
    --cc=alibuda@linux.alibaba.com \
    --cc=dust.li@linux.ibm.com \
    --cc=guwen@linux.alibaba.com \
    --cc=linux-rdma@vger.kernel.org \
    --cc=linux-s390@vger.kernel.org \
    --cc=mjambigi@linux.ibm.com \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=sidraya@linux.ibm.com \
    --cc=tonylu@linux.alibaba.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.