Skip to contentSkip to conversation

Patch "target: Avoid early CMD_T_PRE_EXECUTE failures during ABORT_TASK" has been added to the 4.9-stable tree

PATCH [email protected] 1 participant 1 message Jan 13, 2018

Subsystems (2)
lore
Share & tools
lore

[email protected]

author maintainer Applied
#0 lore raw

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 1c21a48055a67ceb693e9c2587824a8de60a217c Mon 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(stru
 		spin_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