Patch "target: Avoid early CMD_T_PRE_EXECUTE failures during ABORT_TASK" has been added to the 4.9-stable tree
Subsystems (2)
This is a note to let you know that I've just added the patch titled
target: Avoid early CMD_T_PRE_EXECUTE failures during ABORT_TASK
to the 4.9-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
target-avoid-early-cmd_t_pre_execute-failures-during-abort_task.patch
and it can be found in the queue-4.9 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
1c21a48055a67ceb693e9c2587824a8de60a217cMon Sep 17 00:00:00 2001
From: Nicholas Bellinger <[email protected]>
Date: Fri, 27 Oct 2017 22:19:26 -0800
Subject: target: Avoid early CMD_T_PRE_EXECUTE failures during ABORT_TASK
From: Nicholas Bellinger <[email protected]>
commit 1c21a48055a67ceb693e9c2587824a8de60a217c upstream.
This patch fixes bug where early se_cmd exceptions that occur before backend execution can result in use-after-free if/when a subsequent ABORT_TASK occurs for the same tag.
Since an early se_cmd exception will have had se_cmd added to se_session->sess_cmd_list via target_get_sess_cmd(), it will not have CMD_T_COMPLETE set by the usual target_complete_cmd() backend completion path.
This causes a subsequent ABORT_TASK + __target_check_io_state() to signal ABORT_TASK should proceed. As core_tmr_abort_task() executes, it will bring the outstanding se_cmd->cmd_kref count down to zero releasing se_cmd, after se_cmd has already been queued with error status into fabric driver response path code.
To address this bug, introduce a CMD_T_PRE_EXECUTE bit that is set at target_get_sess_cmd() time, and cleared immediately before backend driver dispatch in target_execute_cmd() once CMD_T_ACTIVE is set.
Then, check CMD_T_PRE_EXECUTE within __target_check_io_state() to determine when an early exception has occured, and avoid aborting this se_cmd since it will have already been queued into fabric driver response path code.
--- drivers/target/target_core_tmr.c | 9 +++++++++ drivers/target/target_core_transport.c | 2 ++ include/target/target_core_base.h | 1 + 3 files changed, 12 insertions(+)
drivers/target/target_core_tmr.c +9 -0
@@ -133,6 +133,15 @@ static bool __target_check_io_state(struspin_unlock (&se_cmd->t_state_lock);return false; } +if (se_cmd->transport_state &CMD_T_PRE_EXECUTE ) { +if (se_cmd->scsi_status) { +pr_debug ("Attempted to abort io tag: %llu early failure" +" status: 0x%02x\n" , se_cmd->tag, + se_cmd->scsi_status); +spin_unlock (&se_cmd->t_state_lock); +return false; + } + }if (sess->sess_tearing_down || se_cmd->cmd_wait_set) {pr_debug ("Attempted to abort io tag: %llu already shutdown," " skipping\n" , se_cmd->tag);
drivers/target/target_core_transport.c +2 -0
@@ -1939,6 +1939,7 @@ void target_execute_cmd(struct se_cmd *c } cmd->t_state =TRANSPORT_PROCESSING ; + cmd->transport_state &= ~CMD_T_PRE_EXECUTE ; cmd->transport_state |=CMD_T_ACTIVE |CMD_T_BUSY |CMD_T_SENT ;spin_unlock_irq (&cmd->t_state_lock);
@@ -2592,6 +2593,7 @@ int target_get_sess_cmd(struct se_cmd *s ret = -ESHUTDOWN ; goto out; } + se_cmd->transport_state |=CMD_T_PRE_EXECUTE ;list_add_tail (&se_cmd->se_cmd_list, &se_sess->sess_cmd_list); out:spin_unlock_irqrestore (&se_sess->sess_cmd_lock, flags);
include/target/target_core_base.h +1 -0
@@ -493,6 +493,7 @@ struct se_cmd {#define CMD_T_BUSY (1 << 9)#define CMD_T_TAS (1 << 10)#define CMD_T_FABRIC_STOP (1 << 11) +#define CMD_T_PRE_EXECUTE (1 << 12)spinlock_t t_state_lock;struct kref cmd_kref;struct completion t_transport_stop_comp;
Patches currently in stable-queue which might be from [email protected] are
queue-4.9/iscsi-target-make-task_reassign-use-proper-se_cmd-cmd_kref.patch queue-4.9/target-avoid-early-cmd_t_pre_execute-failures-during-abort_task.patch