* FAILED: patch "[PATCH] net/smc: fix use-after-free in smc_rx_pipe_buf_release()" failed to apply to 5.15-stable tree
@ 2026-09-03 15:18 gregkh
2026-09-10 0:17 ` [PATCH 5.15.y 1/2] net/smc: Resolve the race between link group access and termination Sasha Levin
0 siblings, 1 reply; 3+ messages in thread
From: gregkh @ 2026-09-03 15:18 UTC (permalink / raw)
To: hidayath, horms, kuba, mjambigi; +Cc: stable
The patch below does not apply to the 5.15-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 <stable@vger.kernel.org>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-5.15.y
git checkout FETCH_HEAD
git cherry-pick -x c924884743e948e25625b7fbf3ee2a9325a204a7
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<stable@vger.kernel.org>' --in-reply-to '2026090344-judgingly-mace-1efd@gregkh' --subject-prefix 'PATCH 5.15.y' 'HEAD^..'
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From c924884743e948e25625b7fbf3ee2a9325a204a7 Mon Sep 17 00:00:00 2001
From: Hidayath Khan <hidayath@linux.ibm.com>
Date: Thu, 20 Aug 2026 09:46:42 +0200
Subject: [PATCH] net/smc: fix use-after-free in smc_rx_pipe_buf_release()
smc_rx_splice() hands RMB pages to a pipe and takes a socket reference
per entry so the smc_sock stays alive until the reader finishes. The
connection does not: a concurrent close runs smc_conn_free(), which
releases the receive buffer back to the link group pool.
smc_rx_pipe_buf_release() tests sk_state before taking the socket lock.
The state can change between the test and the lock, and
smc_rx_update_cons() then dereferences conn->rmb_desc and walks
conn->lgr, which smc_conn_free() has already released. On the
is_reg_err path smcr_buf_unuse() frees the descriptor outright, so
this is a use-after-free.
Take the socket lock first and test conn->freed instead.
smc_conn_free() sets that flag before releasing anything, and every
caller holds the socket lock. The two paths exclude each other: either
the pipe release runs first with everything valid, or it sees the flag
and skips the update.
Fixes: 9014db202cb7 ("smc: add support for splice()")
Cc: stable@vger.kernel.org
Reviewed-by: Mahanta Jambigi <mjambigi@linux.ibm.com>
Signed-off-by: Hidayath Khan <hidayath@linux.ibm.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20260820074642.966856-3-hidayath@linux.ibm.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
diff --git a/net/smc/smc_rx.c b/net/smc/smc_rx.c
index 5c9e4d8b57de..197fddc6271f 100644
--- a/net/smc/smc_rx.c
+++ b/net/smc/smc_rx.c
@@ -115,16 +115,15 @@ static void smc_rx_pipe_buf_release(struct pipe_inode_info *pipe,
struct pipe_buffer *buf)
{
struct smc_spd_priv *priv = (struct smc_spd_priv *)buf->private;
+ struct smc_connection *conn = &priv->smc->conn;
struct smc_sock *smc = priv->smc;
- struct smc_connection *conn;
struct sock *sk = &smc->sk;
- if (sk->sk_state == SMC_CLOSED ||
- sk->sk_state == SMC_PEERFINCLOSEWAIT ||
- sk->sk_state == SMC_APPFINCLOSEWAIT)
- goto out;
- conn = &smc->conn;
lock_sock(sk);
+ if (conn->freed) {
+ release_sock(sk);
+ goto out;
+ }
smc_rx_update_cons(smc, priv->len);
release_sock(sk);
if (atomic_sub_and_test(priv->len, &conn->splice_pending))
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [PATCH 5.15.y 1/2] net/smc: Resolve the race between link group access and termination
2026-09-03 15:18 FAILED: patch "[PATCH] net/smc: fix use-after-free in smc_rx_pipe_buf_release()" failed to apply to 5.15-stable tree gregkh
@ 2026-09-10 0:17 ` Sasha Levin
2026-09-10 0:17 ` [PATCH 5.15.y 2/2] net/smc: fix use-after-free in smc_rx_pipe_buf_release() Sasha Levin
0 siblings, 1 reply; 3+ messages in thread
From: Sasha Levin @ 2026-09-10 0:17 UTC (permalink / raw)
To: stable; +Cc: Wen Gu, David S. Miller, Sasha Levin
From: Wen Gu <guwen@linux.alibaba.com>
[ Upstream commit 61f434b0280ed65495831f1b6e1a5c21a90f47c6 ]
We encountered some crashes caused by the race between the access
and the termination of link groups.
Here are some of panic stacks we met:
1) Race between smc_clc_wait_msg() and __smc_lgr_terminate()
BUG: kernel NULL pointer dereference, address: 00000000000002f0
Workqueue: smc_hs_wq smc_listen_work [smc]
RIP: 0010:smc_clc_wait_msg+0x3eb/0x5c0 [smc]
Call Trace:
<TASK>
? smc_clc_send_accept+0x45/0xa0 [smc]
? smc_clc_send_accept+0x45/0xa0 [smc]
smc_listen_work+0x783/0x1220 [smc]
? finish_task_switch+0xc4/0x2e0
? process_one_work+0x1ad/0x3c0
process_one_work+0x1ad/0x3c0
worker_thread+0x4c/0x390
? rescuer_thread+0x320/0x320
kthread+0x149/0x190
? set_kthread_struct+0x40/0x40
ret_from_fork+0x1f/0x30
</TASK>
smc_listen_work() abnormal case like port error
---------------------------------------------------------------
| __smc_lgr_terminate()
| |- smc_conn_kill()
| |- smc_lgr_unregister_conn()
| |- set conn->lgr = NULL
smc_clc_wait_msg() |
|- access conn->lgr (panic) |
2) Race between smc_setsockopt() and __smc_lgr_terminate()
BUG: kernel NULL pointer dereference, address: 00000000000002e8
RIP: 0010:smc_setsockopt+0x17a/0x280 [smc]
Call Trace:
<TASK>
__sys_setsockopt+0xfc/0x190
__x64_sys_setsockopt+0x20/0x30
do_syscall_64+0x34/0x90
entry_SYSCALL_64_after_hwframe+0x44/0xae
</TASK>
smc_setsockopt() abnormal case like port error
--------------------------------------------------------------
| __smc_lgr_terminate()
| |- smc_conn_kill()
| |- smc_lgr_unregister_conn()
| |- set conn->lgr = NULL
mod_delayed_work() |
|- access conn->lgr (panic) |
There are some other panic places and they are caused by the
similar reason as described above, which is accessing link
group after termination, thus getting a NULL pointer or invalid
resource.
Currently, there seems to be no synchronization between the
link group access and a sudden termination of it. This patch
tries to fix this by introducing reference count of link group
and not freeing link group until reference count is zero.
Link group might be referred to by links or smc connections. So
the operation to the link group reference count can be concluded
as follows:
object [hold or initialized as 1] [put]
-------------------------------------------------------------------
link group smc_lgr_create() smc_lgr_free()
connections smc_conn_create() smc_conn_free()
links smcr_link_init() smcr_link_clear()
Througth this way, we extend the life cycle of link group and
ensure it is longer than the life cycle of connections and links
above it, so that avoid invalid access to link group after its
termination.
Signed-off-by: Wen Gu <guwen@linux.alibaba.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Keep only the connection teardown state needed by target commit
c924884743e948e25625b7fbf3ee2a9325a204a7 ("net/smc: fix use-after-free
in smc_rx_pipe_buf_release()") for this 5.15 dependency backport.
Add conn->freed, reset it when creating a connection, and set it before
smc_conn_free() releases connection resources. Also set it when
smc_lgr_unregister_conn() detaches the connection: on this stable tree,
forced termination may unregister and free the link group without first
calling smc_conn_free(). The target can then use the flag under the socket
lock to avoid accessing either reused buffers or a detached link group.
Drop the upstream link-group reference-counting changes and their new
helper functions. They are unnecessary for the target's teardown check
and conflict with the older link initialization and link-group cleanup
code, which lacks smc_wr_free_lgr_mem(). Preserve the existing 5.15
link-group lifetime and conn->lgr clearing behavior.
[ sashal: Reduced backport -- upstream 61f434b0280ed touches 3 file(s), this
backport carries 2. Not backported here:
net/smc/smc_core.h
This note is generated from the file lists only; see the resolution record
for the reasoning. ]
Stable-dep-of: c924884743e9 ("net/smc: fix use-after-free in smc_rx_pipe_buf_release()")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/smc/smc.h | 1 +
net/smc/smc_core.c | 6 +++++-
2 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/net/smc/smc.h b/net/smc/smc.h
index 6455371430a3c..339a467c03d02 100644
--- a/net/smc/smc.h
+++ b/net/smc/smc.h
@@ -217,6 +217,7 @@ struct smc_connection {
*/
u64 peer_token; /* SMC-D token of peer */
u8 killed : 1; /* abnormal termination */
+ u8 freed : 1; /* connection released */
u8 out_of_sync : 1; /* out of sync with peer */
};
diff --git a/net/smc/smc_core.c b/net/smc/smc_core.c
index f6119f29b44ce..c2a8fc7a03ff8 100644
--- a/net/smc/smc_core.c
+++ b/net/smc/smc_core.c
@@ -217,6 +217,8 @@ static void smc_lgr_unregister_conn(struct smc_connection *conn)
__smc_lgr_unregister_conn(conn);
}
write_unlock_bh(&lgr->conns_lock);
+ /* Termination can unregister a connection without smc_conn_free(). */
+ conn->freed = 1;
conn->lgr = NULL;
}
@@ -1049,8 +1051,9 @@ void smc_conn_free(struct smc_connection *conn)
{
struct smc_link_group *lgr = conn->lgr;
- if (!lgr)
+ if (!lgr || conn->freed)
return;
+ conn->freed = 1;
if (lgr->is_smcd) {
if (!list_empty(&lgr->list))
smc_ism_unset_conn(conn);
@@ -1740,6 +1743,7 @@ int smc_conn_create(struct smc_sock *smc, struct smc_init_info *ini)
goto out;
}
}
+ conn->freed = 0;
conn->local_tx_ctrl.common.type = SMC_CDC_MSG_TYPE;
conn->local_tx_ctrl.len = SMC_WR_TX_SIZE;
conn->urg_state = SMC_URG_READ;
--
2.53.0
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [PATCH 5.15.y 2/2] net/smc: fix use-after-free in smc_rx_pipe_buf_release()
2026-09-10 0:17 ` [PATCH 5.15.y 1/2] net/smc: Resolve the race between link group access and termination Sasha Levin
@ 2026-09-10 0:17 ` Sasha Levin
0 siblings, 0 replies; 3+ messages in thread
From: Sasha Levin @ 2026-09-10 0:17 UTC (permalink / raw)
To: stable
Cc: Hidayath Khan, Mahanta Jambigi, Simon Horman, Jakub Kicinski,
Sasha Levin
From: Hidayath Khan <hidayath@linux.ibm.com>
[ Upstream commit c924884743e948e25625b7fbf3ee2a9325a204a7 ]
smc_rx_splice() hands RMB pages to a pipe and takes a socket reference
per entry so the smc_sock stays alive until the reader finishes. The
connection does not: a concurrent close runs smc_conn_free(), which
releases the receive buffer back to the link group pool.
smc_rx_pipe_buf_release() tests sk_state before taking the socket lock.
The state can change between the test and the lock, and
smc_rx_update_cons() then dereferences conn->rmb_desc and walks
conn->lgr, which smc_conn_free() has already released. On the
is_reg_err path smcr_buf_unuse() frees the descriptor outright, so
this is a use-after-free.
Take the socket lock first and test conn->freed instead.
smc_conn_free() sets that flag before releasing anything, and every
caller holds the socket lock. The two paths exclude each other: either
the pipe release runs first with everything valid, or it sees the flag
and skips the update.
Fixes: 9014db202cb7 ("smc: add support for splice()")
Cc: stable@vger.kernel.org
Reviewed-by: Mahanta Jambigi <mjambigi@linux.ibm.com>
Signed-off-by: Hidayath Khan <hidayath@linux.ibm.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20260820074642.966856-3-hidayath@linux.ibm.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/smc/smc_rx.c | 11 +++++------
1 file changed, 5 insertions(+), 6 deletions(-)
diff --git a/net/smc/smc_rx.c b/net/smc/smc_rx.c
index 33b5bcafdec7d..318ffb372f384 100644
--- a/net/smc/smc_rx.c
+++ b/net/smc/smc_rx.c
@@ -110,16 +110,15 @@ static void smc_rx_pipe_buf_release(struct pipe_inode_info *pipe,
struct pipe_buffer *buf)
{
struct smc_spd_priv *priv = (struct smc_spd_priv *)buf->private;
+ struct smc_connection *conn = &priv->smc->conn;
struct smc_sock *smc = priv->smc;
- struct smc_connection *conn;
struct sock *sk = &smc->sk;
- if (sk->sk_state == SMC_CLOSED ||
- sk->sk_state == SMC_PEERFINCLOSEWAIT ||
- sk->sk_state == SMC_APPFINCLOSEWAIT)
- goto out;
- conn = &smc->conn;
lock_sock(sk);
+ if (conn->freed) {
+ release_sock(sk);
+ goto out;
+ }
smc_rx_update_cons(smc, priv->len);
release_sock(sk);
if (atomic_sub_and_test(priv->len, &conn->splice_pending))
--
2.53.0
^ permalink raw reply related [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-09-10 0:17 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-03 15:18 FAILED: patch "[PATCH] net/smc: fix use-after-free in smc_rx_pipe_buf_release()" failed to apply to 5.15-stable tree gregkh
2026-09-10 0:17 ` [PATCH 5.15.y 1/2] net/smc: Resolve the race between link group access and termination Sasha Levin
2026-09-10 0:17 ` [PATCH 5.15.y 2/2] net/smc: fix use-after-free in smc_rx_pipe_buf_release() Sasha Levin
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.