From: Sidraya Jayagond <sidraya@linux.ibm.com>
To: Xiang Mei <xmei5@asu.edu>,
"D . Wythe" <alibuda@linux.alibaba.com>,
Dust Li <dust.li@linux.alibaba.com>,
Wenjia Zhang <wenjia@linux.ibm.com>,
Mahanta Jambigi <mjambigi@linux.ibm.com>,
Tony Lu <tonylu@linux.alibaba.com>,
Wen Gu <guwen@linux.alibaba.com>,
netdev@vger.kernel.org
Cc: "David S . Miller" <davem@davemloft.net>,
Eric Dumazet <edumazet@google.com>,
Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
Simon Horman <horms@kernel.org>,
Hans Wippel <hwippel@linux.ibm.com>,
linux-rdma@vger.kernel.org, linux-s390@vger.kernel.org,
Weiming Shi <bestswngs@gmail.com>
Subject: Re: [PATCH net] net/smc: fix UAF in smc_cdc_rx_handler() by pinning the socket
Date: Tue, 30 Jun 2026 11:09:51 +0530 [thread overview]
Message-ID: <cbd7c6c1-15e9-4a9a-aaca-4cbb5bd157c7@linux.ibm.com> (raw)
In-Reply-To: <20260627014948.3049512-1-xmei5@asu.edu>
On 27/06/26 7:19 am, Xiang Mei wrote:
> smc_cdc_rx_handler() looks up the connection by token under the link
> group's conns_lock, drops the lock, and then dereferences conn and the
> smc_sock derived from it, ending in sock_hold(&smc->sk) inside
> smc_cdc_msg_recv(). No reference is held across the lock release.
>
> The only reference pinning the socket while the connection is
> discoverable in the link group is taken in smc_lgr_register_conn()
> (sock_hold) and dropped in __smc_lgr_unregister_conn() (sock_put), both
> under conns_lock. Once the handler drops conns_lock, a concurrent
> close() -> smc_release() -> smc_conn_free() -> smc_lgr_unregister_conn()
> can drop that reference and free the smc_sock, so the handler's later
> sock_hold() runs on freed memory:
>
> WARNING: lib/refcount.c:25 at refcount_warn_saturate
> Workqueue: rxe_wq do_work
> refcount_warn_saturate (lib/refcount.c:25)
> smc_cdc_msg_recv (net/smc/smc_cdc.c:430)
> smc_cdc_rx_handler (net/smc/smc_cdc.c:502)
> smc_wr_rx_tasklet_fn (net/smc/smc_wr.c:445)
> tasklet_action_common (kernel/softirq.c:938)
> handle_softirqs (kernel/softirq.c:622)
> Kernel panic - not syncing: panic_on_warn set
>
> Only SMC-R is affected. The SMC-D receive tasklet is stopped by
> tasklet_kill(&conn->rx_tsklet) in smc_conn_free() before the connection
> is unregistered, so it cannot run concurrently with the free.
>
> Take the socket reference while still holding conns_lock, so the
> registration reference can no longer be the last one, and drop it once
> the handler is done.
>
> Fixes: d7b0e37c1ac1 ("net/smc: restructure CDC message reception")
> Reported-by: Weiming Shi <bestswngs@gmail.com>
> Assisted-by: Claude:claude-opus-4-8
> Signed-off-by: Xiang Mei <xmei5@asu.edu>
> ---
> net/smc/smc_cdc.c | 12 +++++++++---
> 1 file changed, 9 insertions(+), 3 deletions(-)
>
> diff --git a/net/smc/smc_cdc.c b/net/smc/smc_cdc.c
> index 619b3bab3824..b809139d7e87 100644
> --- a/net/smc/smc_cdc.c
> +++ b/net/smc/smc_cdc.c
> @@ -483,21 +483,27 @@ static void smc_cdc_rx_handler(struct ib_wc *wc, void *buf)
> lgr = smc_get_lgr(link);
> read_lock_bh(&lgr->conns_lock);
> conn = smc_lgr_find_conn(ntohl(cdc->token), lgr);
> + if (conn && !conn->out_of_sync)
> + sock_hold(&container_of(conn, struct smc_sock, conn)->sk);
> + else
> + conn = NULL;
> read_unlock_bh(&lgr->conns_lock);
> - if (!conn || conn->out_of_sync)
> + if (!conn)
> return;
> smc = container_of(conn, struct smc_sock, conn);
>
Fix looks correct.
A few nits on the implementation:
container_of() is called twice for the same conn. The conn = NULL
sentinel and the second post unlock check can also be dropped. Flip the
condition, early return inside the lock, compute smc once:
if (!conn || conn->out_of_sync) {
read_unlock_bh(&lgr->conns_lock);
return;
}
smc = container_of(conn, struct smc_sock, conn);
sock_hold(&smc->sk);
read_unlock_bh(&lgr->conns_lock);
Also please initialize smc = NULL at declaration, it's not a bug now
since the early return guards it, just to make it refactor safe.
> if (cdc->prod_flags.failover_validation) {
> smc_cdc_msg_validate(smc, cdc, link);
> - return;
> + goto out;
> }
> if (smc_cdc_before(ntohs(cdc->seqno),
> conn->local_rx_ctrl.seqno))
> /* received seqno is old */
> - return;
> + goto out;
>
> smc_cdc_msg_recv(smc, cdc);
> +out:
> + sock_put(&smc->sk);
> }
>
> static struct smc_wr_rx_handler smc_cdc_rx_handlers[] = {
next prev parent reply other threads:[~2026-06-30 5:40 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-27 1:49 [PATCH net] net/smc: fix UAF in smc_cdc_rx_handler() by pinning the socket Xiang Mei
2026-06-28 1:50 ` sashiko-bot
2026-06-30 5:39 ` Sidraya Jayagond [this message]
2026-06-30 18:18 ` Xiang Mei
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=cbd7c6c1-15e9-4a9a-aaca-4cbb5bd157c7@linux.ibm.com \
--to=sidraya@linux.ibm.com \
--cc=alibuda@linux.alibaba.com \
--cc=bestswngs@gmail.com \
--cc=davem@davemloft.net \
--cc=dust.li@linux.alibaba.com \
--cc=edumazet@google.com \
--cc=guwen@linux.alibaba.com \
--cc=horms@kernel.org \
--cc=hwippel@linux.ibm.com \
--cc=kuba@kernel.org \
--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=tonylu@linux.alibaba.com \
--cc=wenjia@linux.ibm.com \
--cc=xmei5@asu.edu \
/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.