All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Yu Zhang" <yuz08559@gmail.com>
Cc: linux-scsi@vger.kernel.org, target-devel@vger.kernel.org
Subject: Re: [PATCH] scsi: target: tcm_loop: fix tl_nexus use-after-free on concurrent nexus drop
Date: Wed, 14 Oct 2026 01:29:55 +0000	[thread overview]
Message-ID: <sashiko-outbox-170672@kernel.org> (raw)
In-Reply-To: <20261014011739.45941-1-yuz08559@gmail.com>

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] tcm_loop: UAF in I/O path due to port link and nexus drop TOCTOU race
--

commit f5acf49b795a91429ba7f28b4f3ce2e9fca1884a
Author: Yu Zhang <yuz08559@gmail.com>

    scsi: target: tcm_loop: fix tl_nexus use-after-free on concurrent nexus drop
    
    tcm_loop keeps the per-TPG I_T nexus in tl_tpg->tl_nexus with no lock,
    refcount or RCU protection.  The configfs control path that creates and
    destroys it is not serialized: configfs runs concurrent ->store() calls
    in parallel (configfs_write_iter() only holds a per-open-file
    buffer->mutex, and flush_write_buffer() takes frag_sem for read), so two
    writers to the nexus attribute, or a writer racing the transport_status
    or nexus show attribute, all touch tl_nexus concurrently.

[ ... ]

    The I/O submission path (tcm_loop_target_queue_cmd(), tcm_loop_issue_tmr())
    reads tl_nexus without the mutex and is left unchanged: it can run in
    atomic context, and it is already serialized against drop by
    tl_tpg_port_count plus SCSI-midlayer draining (a live scsi_device keeps
    tl_tpg_port_count > 0, which makes tcm_loop_drop_nexus() return -EPERM).
    
    Cc: stable@vger.kernel.org
    Signed-off-by: Yu Zhang <yuz08559@gmail.com>
    Tested-by: Yu Zhang <yuz08559@gmail.com>

> diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c
> index d29830b951f75..980e9e65b788c 100644
> --- a/drivers/target/loopback/tcm_loop.c
> +++ b/drivers/target/loopback/tcm_loop.c

[ ... ]

> @@ -701,17 +708,23 @@ static int tcm_loop_drop_nexus(
>  	struct se_session *se_sess;
>  	struct tcm_loop_nexus *tl_nexus;
>  
> +	mutex_lock(&tpg->tl_nexus_mutex);
>  	tl_nexus = tpg->tl_nexus;
> -	if (!tl_nexus)
> +	if (!tl_nexus) {
> +		mutex_unlock(&tpg->tl_nexus_mutex);
>  		return -ENODEV;
> +	}
>  
>  	se_sess = tl_nexus->se_sess;
> -	if (!se_sess)
> +	if (!se_sess) {
> +		mutex_unlock(&tpg->tl_nexus_mutex);
>  		return -ENODEV;
> +	}
>  
>  	if (atomic_read(&tpg->tl_tpg_port_count)) {
>  		pr_err("Unable to remove TCM_Loop I_T Nexus with active TPG port count: %d\n",
>  		       atomic_read(&tpg->tl_tpg_port_count));
> +		mutex_unlock(&tpg->tl_nexus_mutex);
>  		return -EPERM;
>  	}
>  

[Severity: High]
Does this port count check prevent a concurrent port link from immediately
incrementing the count and issuing I/O before the nexus is freed?

While this check is under tl_nexus_mutex, tcm_loop_port_link() increments
the port count and calls scsi_add_device() without holding tl_nexus_mutex:

drivers/target/loopback/tcm_loop.c:tcm_loop_port_link() {
    ...
    atomic_inc_mb(&tl_tpg->tl_tpg_port_count);
    /*
     * Add Linux/SCSI struct scsi_device by HCTL
     */
    scsi_add_device(tl_hba->sh, 0, tl_tpg->tl_tpgt, lun->unpacked_lun);
    ...
}

If tcm_loop_drop_nexus() sees a count of 0 and proceeds to clear and free
tl_nexus, could a concurrent configfs symlink creation (tcm_loop_port_link)
transition the count to 1 and queue INQUIRY commands via scsi_add_device()?

Since scsi_add_device() synchronously queues commands via
tcm_loop_target_queue_cmd(), which locklessly reads tl_tpg->tl_nexus, could
the I/O path dereference the newly freed tl_nexus->se_sess if it races with
tcm_loop_drop_nexus() clearing and freeing it?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261014011739.45941-1-yuz08559@gmail.com?part=1

      reply	other threads:[~2026-10-14  1:29 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-14  1:17 [PATCH] scsi: target: tcm_loop: fix tl_nexus use-after-free on concurrent nexus drop Yu Zhang
2026-10-14  1:29 ` sashiko-bot [this message]

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=sashiko-outbox-170672@kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=linux-scsi@vger.kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    --cc=target-devel@vger.kernel.org \
    --cc=yuz08559@gmail.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.