From e5ffc4ef50f03f63c285c08301c80be8b37bab79 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sat, 13 Jan 2018 18:33:46 +0100 Subject: [PATCH] 4.4-stable patches added patches: iscsi-target-make-task_reassign-use-proper-se_cmd-cmd_kref.patch target-avoid-early-cmd_t_pre_execute-failures-during-abort_task.patch --- ..._reassign-use-proper-se_cmd-cmd_kref.patch | 85 +++++++++++++++++ queue-4.4/series | 2 + ...e_execute-failures-during-abort_task.patch | 94 +++++++++++++++++++ 3 files changed, 181 insertions(+) create mode 100644 queue-4.4/iscsi-target-make-task_reassign-use-proper-se_cmd-cmd_kref.patch create mode 100644 queue-4.4/target-avoid-early-cmd_t_pre_execute-failures-during-abort_task.patch diff --git a/queue-4.4/iscsi-target-make-task_reassign-use-proper-se_cmd-cmd_kref.patch b/queue-4.4/iscsi-target-make-task_reassign-use-proper-se_cmd-cmd_kref.patch new file mode 100644 index 00000000000..d1d2d332543 --- /dev/null +++ b/queue-4.4/iscsi-target-make-task_reassign-use-proper-se_cmd-cmd_kref.patch @@ -0,0 +1,85 @@ +From ae072726f6109bb1c94841d6fb3a82dde298ea85 Mon Sep 17 00:00:00 2001 +From: Nicholas Bellinger +Date: Fri, 27 Oct 2017 12:32:59 -0700 +Subject: iscsi-target: Make TASK_REASSIGN use proper se_cmd->cmd_kref + +From: Nicholas Bellinger + +commit ae072726f6109bb1c94841d6fb3a82dde298ea85 upstream. + +Since commit 59b6986dbf fixed a potential NULL pointer dereference +by allocating a se_tmr_req for ISCSI_TM_FUNC_TASK_REASSIGN, the +se_tmr_req is currently leaked by iscsit_free_cmd() because no +iscsi_cmd->se_cmd.se_tfo was associated. + +To address this, treat ISCSI_TM_FUNC_TASK_REASSIGN like any other +TMR and call transport_init_se_cmd() + target_get_sess_cmd() to +setup iscsi_cmd->se_cmd.se_tfo with se_cmd->cmd_kref of 2. + +This will ensure normal release operation once se_cmd->cmd_kref +reaches zero and target_release_cmd_kref() is invoked, se_tmr_req +will be released via existing target_free_cmd_mem() and +core_tmr_release_req() code. + +Reported-by: Donald White +Cc: Donald White +Cc: Mike Christie +Cc: Hannes Reinecke +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + + + +--- + drivers/target/iscsi/iscsi_target.c | 20 +++++++------------- + 1 file changed, 7 insertions(+), 13 deletions(-) + +--- a/drivers/target/iscsi/iscsi_target.c ++++ b/drivers/target/iscsi/iscsi_target.c +@@ -1759,7 +1759,6 @@ iscsit_handle_task_mgt_cmd(struct iscsi_ + struct iscsi_tmr_req *tmr_req; + struct iscsi_tm *hdr; + int out_of_order_cmdsn = 0, ret; +- bool sess_ref = false; + u8 function, tcm_function = TMR_UNKNOWN; + + hdr = (struct iscsi_tm *) buf; +@@ -1801,18 +1800,17 @@ iscsit_handle_task_mgt_cmd(struct iscsi_ + buf); + } + ++ transport_init_se_cmd(&cmd->se_cmd, &iscsi_ops, ++ conn->sess->se_sess, 0, DMA_NONE, ++ TCM_SIMPLE_TAG, cmd->sense_buffer + 2); ++ ++ target_get_sess_cmd(&cmd->se_cmd, true); ++ + /* + * TASK_REASSIGN for ERL=2 / connection stays inside of + * LIO-Target $FABRIC_MOD + */ + if (function != ISCSI_TM_FUNC_TASK_REASSIGN) { +- transport_init_se_cmd(&cmd->se_cmd, &iscsi_ops, +- conn->sess->se_sess, 0, DMA_NONE, +- TCM_SIMPLE_TAG, cmd->sense_buffer + 2); +- +- target_get_sess_cmd(&cmd->se_cmd, true); +- sess_ref = true; +- + switch (function) { + case ISCSI_TM_FUNC_ABORT_TASK: + tcm_function = TMR_ABORT_TASK; +@@ -1951,12 +1949,8 @@ attach: + * For connection recovery, this is also the default action for + * TMR TASK_REASSIGN. + */ +- if (sess_ref) { +- pr_debug("Handle TMR, using sess_ref=true check\n"); +- target_put_sess_cmd(&cmd->se_cmd); +- } +- + iscsit_add_cmd_to_response_queue(cmd, conn, cmd->i_state); ++ target_put_sess_cmd(&cmd->se_cmd); + return 0; + } + EXPORT_SYMBOL(iscsit_handle_task_mgt_cmd); diff --git a/queue-4.4/series b/queue-4.4/series index 4910ba8c091..ef0d27206bd 100644 --- a/queue-4.4/series +++ b/queue-4.4/series @@ -67,3 +67,5 @@ bpf-refactor-fixup_bpf_calls.patch bpf-adjust-insn_aux_data-when-patching-insns.patch bpf-prevent-out-of-bounds-speculation.patch bpf-array-fix-overflow-in-max_entries-and-undefined-behavior-in-index_mask.patch +iscsi-target-make-task_reassign-use-proper-se_cmd-cmd_kref.patch +target-avoid-early-cmd_t_pre_execute-failures-during-abort_task.patch diff --git a/queue-4.4/target-avoid-early-cmd_t_pre_execute-failures-during-abort_task.patch b/queue-4.4/target-avoid-early-cmd_t_pre_execute-failures-during-abort_task.patch new file mode 100644 index 00000000000..41210fc0739 --- /dev/null +++ b/queue-4.4/target-avoid-early-cmd_t_pre_execute-failures-during-abort_task.patch @@ -0,0 +1,94 @@ +From 1c21a48055a67ceb693e9c2587824a8de60a217c Mon Sep 17 00:00:00 2001 +From: Nicholas Bellinger +Date: Fri, 27 Oct 2017 22:19:26 -0800 +Subject: target: Avoid early CMD_T_PRE_EXECUTE failures during ABORT_TASK + +From: Nicholas Bellinger + +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. + +Reported-by: Donald White +Cc: Donald White +Cc: Mike Christie +Cc: Hannes Reinecke +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + + +--- + 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(+) + +--- a/drivers/target/target_core_tmr.c ++++ b/drivers/target/target_core_tmr.c +@@ -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); +--- a/drivers/target/target_core_transport.c ++++ b/drivers/target/target_core_transport.c +@@ -1933,6 +1933,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); + +@@ -2572,6 +2573,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); +--- a/include/target/target_core_base.h ++++ b/include/target/target_core_base.h +@@ -496,6 +496,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; -- 2.47.3