All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Xiang Mei" <xmei5@asu.edu>
Cc: linux-s390@vger.kernel.org, "Heiko Carstens" <hca@linux.ibm.com>,
	"Alexander Gordeev" <agordeev@linux.ibm.com>,
	"Vasily Gorbik" <gor@linux.ibm.com>
Subject: Re: [PATCH net] net/smc: fix UAF in smc_cdc_rx_handler() by pinning the socket
Date: Sun, 28 Jun 2026 01:50:04 +0000	[thread overview]
Message-ID: <20260628015005.709CB1F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260627014948.3049512-1-xmei5@asu.edu>

Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:

Pre-existing issues:
- [High] Asynchronous `tx_work` can be queued during socket release and execute after the socket is freed, leading to a Use-After-Free.
- [High] Concurrent execution of `smc_conn_free()` and `smc_cdc_rx_handler()` causes a Use-After-Free on connection buffers and the link group.
- [High] Concurrent modification of bitfields (`out_of_sync`, `freed`, `killed`) in `struct smc_connection` causes torn writes and lost state updates.
- [High] Cancelling `abort_work` in `smc_conn_free()` without checking its return value leaks a socket reference.
--

commit 2ba91a5beb3d341e982b17474cb075d5a25cb381
Author: Xiang Mei <xmei5@asu.edu>

net/smc: fix UAF in smc_cdc_rx_handler() by pinning the socket

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. This patch takes the socket reference while
still holding conns_lock to prevent the socket from being freed
concurrently, and drops the reference once the handler is done.

> diff --git a/net/smc/smc_cdc.c b/net/smc/smc_cdc.c
> index 619b3bab38248..b809139d7e870 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);

[Severity: High]
This is a pre-existing issue, but does dropping lgr->conns_lock here leave the
connection buffers and link group vulnerable to concurrent freeing?

Looking at net/smc/smc_core.c:smc_conn_free(), the buffers can be freed
concurrently:

    smc_buf_unuse(conn, lgr); /* allow buffer reuse */

Because smc_conn_free() doesn't synchronize with the RX handler for SMC-R,
could the subsequent call to smc_cdc_msg_recv_action() dereference freed memory
when it accesses conn->rmb_desc->len or conn->lgr?

> -	if (!conn || conn->out_of_sync)
> +	if (!conn)
>  		return;
>  	smc = container_of(conn, struct smc_sock, conn);
>  
>  	if (cdc->prod_flags.failover_validation) {
>  		smc_cdc_msg_validate(smc, cdc, link);

[Severity: High]
This isn't a bug introduced by this patch, but can concurrent bitfield
modifications lead to lost state updates here?

In net/smc/smc_cdc.c:smc_cdc_msg_validate(), conn->out_of_sync is set without a
lock from the softirq context:

    conn->out_of_sync = 1; /* prevent any further receives */

Concurrently, net/smc/smc_core.c:smc_conn_free() modifies another bit in the
same byte from process context:

    conn->freed = 1;

Since these bitfields share the same byte in struct smc_connection, could the
read-modify-write on these bitfields cause the freed = 1 update to be
lost, resulting in a double-free if the connection is torn down again?

[Severity: High]
This is another pre-existing issue, but does cancelling the abort work without
checking its return value cause a socket reference leak?

In net/smc/smc_cdc.c:smc_cdc_msg_validate():

    sock_hold(&smc->sk);
    if (!queue_work(smc_close_wq, &conn->abort_work))
        sock_put(&smc->sk);

If net/smc/smc_core.c:smc_conn_free() successfully cancels this pending work:

    if (current_work() != &conn->abort_work)
        cancel_work_sync(&conn->abort_work);

The work function won't execute to drop the reference. Since smc_conn_free()
ignores the return value of cancel_work_sync(), does the socket reference
remain permanently leaked?

> -		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);

[Severity: High]
This is a pre-existing issue, but can this lead to a use-after-free of the
smc socket during release?

In net/smc/smc_cdc.c:smc_cdc_msg_recv_action(), if the socket lock is held
by the release thread, the handler sets a flag instead of queuing work:

    conn->tx_in_release_sock = true;

When net/smc/af_smc.c:smc_release() runs, it invokes release_sock(), causing
net/smc/af_smc.c:smc_release_cb() to queue the work asynchronously:

    smc_tx_pending(&smc->conn);

Since smc_release() drops the final socket reference right after this:

    sock_put(sk); /* final sock_put */

Could the asynchronous net/smc/smc_tx.c:smc_tx_work() execute after the socket
is freed, resulting in a use-after-free when it dereferences the socket
structure?

> +out:
> +	sock_put(&smc->sk);
>  }

[ ... ]

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260627014948.3049512-1-xmei5@asu.edu?part=1

  reply	other threads:[~2026-06-28  1:50 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 [this message]
2026-06-30  5:39 ` Sidraya Jayagond
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=20260628015005.709CB1F000E9@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=agordeev@linux.ibm.com \
    --cc=gor@linux.ibm.com \
    --cc=hca@linux.ibm.com \
    --cc=linux-s390@vger.kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    --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.