Linux SCSI subsystem development
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Laurence Oberman" <loberman@redhat.com>
Cc: linux-scsi@vger.kernel.org, target-devel@vger.kernel.org
Subject: Re: [PATCH v3 1/4] scsi: target: iscsi: Complete an aborted WRITE stuck before the first R2T
Date: Mon, 26 Oct 2026 13:13:13 +0000	[thread overview]
Message-ID: <sashiko-outbox-185288@kernel.org> (raw)
In-Reply-To: <20261026124344.745124-2-loberman@redhat.com>

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] scsi: target: iscsi: UAF on cmd after iscsit_sequence_cmd() aborts write
--

commit bf534eddda8811708a661c23a1fc1d455c52b52d
Author: Laurence Oberman <loberman@redhat.com>

scsi: target: iscsi: Complete an aborted WRITE stuck before the first R2T

This commit completes WRITE commands in TRANSPORT_WRITE_PENDING that were
aborted before the first R2T is sent in iscsit_execute_cmd(). It also adds
a completion claim flag under se_cmd.t_state_lock so that only one of
iscsit_execute_cmd() or iscsit_release_commands_from_conn() completes the
command.

> diff --git a/drivers/target/iscsi/iscsi_target_erl1.c b/drivers/target/iscsi/iscsi_target_erl1.c
> index d8ca06e697d63..cf72c79be355a 100644
> --- a/drivers/target/iscsi/iscsi_target_erl1.c
> +++ b/drivers/target/iscsi/iscsi_target_erl1.c
> @@ -927,8 +927,16 @@ int iscsit_execute_cmd(struct iscsit_cmd *cmd, int ooo)
>  
>  			if (!(cmd->cmd_flags &
>  					ICF_NON_IMMEDIATE_UNSOLICITED_DATA)) {
> -				if (cmd->se_cmd.transport_state & CMD_T_ABORTED)
> +				/*
> +				 * No R2T has been sent for this command yet,
> +				 * so returning here leaves the initiator with
> +				 * nothing to send and no DataOut timer armed.
> +				 * Complete it, or nothing ever will.
> +				 */
> +				if (cmd->se_cmd.transport_state & CMD_T_ABORTED) {
> +					iscsit_complete_aborted_cmd(cmd);
>  					return 0;
> +				}

[Severity: High]
Can completing the command here cause a use-after-free on cmd in the
callers of iscsit_sequence_cmd()?

When an iSCSI WRITE arrives with immediate data whose total data length
exceeds FirstBurstLength and with ISCSI_FLAG_CMD_FINAL set on the Command
PDU (so cmd->immediate_data == 1 and cmd->unsolicited_data == 0),
iscsit_process_scsi_cmd() calls transport_generic_new_cmd(), which adds
cmd->se_cmd to dev->queues[cpuid].state_list with cmd_kref == 2 (initial
kref plus SCF_ACK_KREF).

If an ABORT_TASK TMR, a same-session LUN_RESET, or a cross-session
LUN_RESET with emulate_tas == 0 aborts the command before
iscsit_execute_cmd() runs, __target_check_io_state() sets CMD_T_ABORTED
without CMD_T_TAS.

When iscsit_get_immediate_data() or cxgbit_get_immediate_data() then calls
iscsit_sequence_cmd() -> iscsit_execute_cmd(), iscsit_complete_aborted_cmd()
calls target_complete_cmd() -> target_cmd_interrupted(), queueing
target_abort_work on target_completion_wq. On another CPU,
target_abort_work -> target_handle_abort() runs iscsit_aborted_task(),
drops SCF_ACK_KREF via target_put_sess_cmd(), and calls
transport_cmd_check_stop_to_fabric() -> lio_check_stop_free() ->
target_put_sess_cmd() -> iscsit_release_cmd() -> target_free_tag(), which
returns the cmd slot to se_sess->sess_tag_pool.

However, after iscsit_sequence_cmd() returns CMDSN_NORMAL_OPERATION (0),
both drivers/target/iscsi/iscsi_target.c:iscsit_get_immediate_data() and
drivers/target/iscsi/cxgbit/cxgbit_target.c:cxgbit_get_immediate_data()
still dereference cmd without holding a reference on cmd->se_cmd:

drivers/target/iscsi/iscsi_target.c:iscsit_get_immediate_data() {
    ...
		cmdsn_ret = iscsit_sequence_cmd(cmd->conn, cmd,
					(unsigned char *)hdr, hdr->cmdsn);
		if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER)
			return -1;

		if (cmd->sense_reason || cmdsn_ret == CMDSN_LOWER_THAN_EXP) {
			target_put_sess_cmd(&cmd->se_cmd);

			return 0;
		} else if (cmd->unsolicited_data)
			iscsit_set_unsolicited_dataout(cmd);
    ...
}

If the tag slot has already been reallocated from se_sess->sess_tag_pool,
wouldn't reading cmd->sense_reason or cmd->unsolicited_data inspect the
new command and potentially call target_put_sess_cmd() or
iscsit_set_unsolicited_dataout() on the reallocated command?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261026124344.745124-1-loberman@redhat.com?part=1

  reply	other threads:[~2026-10-26 13:13 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-26 12:43 [PATCH v3 0/4] scsi: target: iscsi: fix stalled and doubly completed aborted WRITEs Laurence Oberman
2026-10-26 12:43 ` [PATCH v3 1/4] scsi: target: iscsi: Complete an aborted WRITE stuck before the first R2T Laurence Oberman
2026-10-26 13:13   ` sashiko-bot [this message]
2026-10-26 12:43 ` [PATCH v3 2/4] scsi: target: iscsi: Complete an aborted WRITE when a new R2T would be sent Laurence Oberman
2026-10-26 13:13   ` sashiko-bot
2026-10-26 13:42     ` Laurence Oberman
2026-10-26 12:43 ` [PATCH v3 3/4] scsi: target: iscsi: Claim the completion in __iscsit_check_dataout_hdr() Laurence Oberman
2026-10-26 12:43 ` [PATCH v3 4/4] scsi: target: iscsi: Claim the completion on the DataOut submit path Laurence Oberman
2026-10-26 13:08   ` 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=sashiko-outbox-185288@kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=linux-scsi@vger.kernel.org \
    --cc=loberman@redhat.com \
    --cc=sashiko-reviews@lists.linux.dev \
    --cc=target-devel@vger.kernel.org \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox