From: sashiko-bot@kernel.org
To: "Yehyeong Lee" <yhlee@isslab.korea.ac.kr>
Cc: linux-scsi@vger.kernel.org
Subject: Re: [PATCH v2 1/2] scsi: libiscsi: only complete a task that has been sent
Date: Fri, 13 Nov 2026 23:57:35 +0000 [thread overview]
Message-ID: <sashiko-outbox-213889@kernel.org> (raw)
In-Reply-To: <20261113233938.397415-2-yhlee@isslab.korea.ac.kr>
Thank you for your contribution! Sashiko AI review found 1 potential
issue to consider:
- [High] scsi: libiscsi: premature ISCSI_TASK_RUNNING before xmit ref
acquisition
--
commit 7682c2a848ebe294348224903c5fc89275f307e1
Author: Yehyeong Lee <yhlee@isslab.korea.ac.kr>
scsi: libiscsi: only complete a task that has been sent
This commit uses smp_store_release() to mark a task ISCSI_TASK_RUNNING in
iscsi_prep_scsi_cmd_pdu() and iscsi_prep_mgmt_task(), and checks for
ISCSI_TASK_RUNNING with smp_load_acquire() in the RX path before
completing a management or rejected task.
> diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
> index 2d04448432a77..83d726043d3e8 100644
> --- a/drivers/scsi/libiscsi.c
> +++ b/drivers/scsi/libiscsi.c
> @@ -429,7 +429,8 @@ static int iscsi_prep_scsi_cmd_pdu(struct iscsi_task *task)
> if (session->tt->init_task && session->tt->init_task(task))
> return -EIO;
>
> - task->state = ISCSI_TASK_RUNNING;
> + /* Pairs with the acquire in the RX task lookups. */
> + smp_store_release(&task->state, ISCSI_TASK_RUNNING);
> session->cmdsn++;
>
> conn->scsicmd_pdus_cnt++;
> @@ -702,7 +703,8 @@ static int iscsi_prep_mgmt_task(struct iscsi_conn *conn,
> if ((hdr->opcode & ISCSI_OPCODE_MASK) == ISCSI_OP_LOGOUT)
> session->state = ISCSI_STATE_LOGGING_OUT;
>
> - task->state = ISCSI_TASK_RUNNING;
> + /* Pairs with the acquire in the RX task lookups. */
> + smp_store_release(&task->state, ISCSI_TASK_RUNNING);
> ISCSI_DBG_SESSION(session, "mgmtpdu [op 0x%x hdr->itt 0x%x "
> "datalen %d]\n", hdr->opcode & ISCSI_OPCODE_MASK,
> hdr->itt, task->data_count);
[Severity: High]
Can the RX path still complete and free task after
smp_store_release(&task->state, ISCSI_TASK_RUNNING) before the transmit
path finishes using it or acquires its reference?
iscsi_data_xmit() runs under session->frwd_lock and calls
iscsi_prep_mgmt_task() (or iscsi_prep_scsi_cmd_pdu()) while task->refcount
is still 1, before iscsi_xmit_task() takes the transmit reference. Since
__iscsi_complete_pdu() and iscsi_handle_reject() run concurrently under
session->back_lock, an unsolicited response or Reject naming that ITT can
arrive in between:
kworker (CPU0) <softirq> (CPU1)
iscsi_data_xmit()
spin_lock_bh(&session->frwd_lock)
iscsi_prep_mgmt_task(conn, task)
smp_store_release(&task->state,
ISCSI_TASK_RUNNING)
__iscsi_complete_pdu()
spin_lock(&session->back_lock)
smp_load_acquire(&task->state)
== ISCSI_TASK_RUNNING
iscsi_complete_task(task, ...)
__iscsi_put_task(session, task)
iscsi_free_task(task)
ISCSI_DBG_SESSION(...)
hdr->opcode <-- use-after-free if cleanup_task
freed task->hdr
iscsi_xmit_task(..., task, false)
iscsi_get_task(task) <-- fails (refcount == 0),
triggers WARN_ON_ONCE(1)
Even if iscsi_get_task() runs before the RX completion, iscsi_xmit_task()
drops session->frwd_lock around session->tt->xmit_task(task); if RX
completes the task during that window and xmit_task() returns an error
such as -EAGAIN, iscsi_xmit_task() unconditionally calls
iscsi_get_task(task) and saves the completed task in conn->task for
retransmission:
drivers/scsi/libiscsi.c:iscsi_xmit_task() {
...
spin_unlock_bh(&session->frwd_lock);
rc = session->tt->xmit_task(task);
spin_lock_bh(&session->frwd_lock);
if (!rc) {
/* done with this task */
task->last_xfer = jiffies;
} else {
/*
* get an extra ref that is released next time we access it
* as conn->task above.
*/
iscsi_get_task(task);
conn->task = task;
}
...
}
In addition, for transports without ihost->workq, iscsi_send_mgmt_task()
and iscsi_queuecommand() call iscsi_prep_mgmt_task() or
iscsi_prep_scsi_cmd_pdu() and invoke session->tt->xmit_task(task) directly
without taking an extra task reference at all, so an RX completion after
ISCSI_TASK_RUNNING is stored frees task while xmit_task() is running (and
if xmit_task() fails, the caller puts task a second time).
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261113233938.397415-1-yhlee@isslab.korea.ac.kr?part=1
next prev parent reply other threads:[~2026-11-13 23:57 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-13 23:39 [PATCH v2 0/2] scsi: libiscsi: tighten management task completion Yehyeong Lee
2026-11-13 23:39 ` [PATCH v2 1/2] scsi: libiscsi: only complete a task that has been sent Yehyeong Lee
2026-11-13 23:57 ` sashiko-bot [this message]
2026-11-13 23:39 ` [PATCH v2 2/2] scsi: libiscsi: do not complete a task sent with a reserved ITT Yehyeong Lee
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-213889@kernel.org \
--to=sashiko-bot@kernel.org \
--cc=linux-scsi@vger.kernel.org \
--cc=sashiko-reviews@lists.linux.dev \
--cc=yhlee@isslab.korea.ac.kr \
/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.