diff options
| author | Nicholas Bellinger <nab@linux-iscsi.org> | 2017-10-27 22:19:26 -0800 |
|---|---|---|
| committer | Ben Hutchings <ben@decadent.org.uk> | 2018-02-13 18:42:18 +0000 |
| commit | a30372543ad9702a2c64d99041576974b2151416 (patch) | |
| tree | eec64d745f30d9140459ccffed020537fb9f5d98 /include/target | |
| parent | 1068ffc77f6f832c96d6ce76120f794340edf526 (diff) | |
| download | linux-a30372543ad9702a2c64d99041576974b2151416.tar.gz linux-a30372543ad9702a2c64d99041576974b2151416.tar.bz2 linux-a30372543ad9702a2c64d99041576974b2151416.zip | |
target: Avoid early CMD_T_PRE_EXECUTE failures during ABORT_TASK
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 <dew@datera.io>
Cc: Donald White <dew@datera.io>
Cc: Mike Christie <mchristi@redhat.com>
Cc: Hannes Reinecke <hare@suse.com>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
[bwh: Backported to 3.16:
- Use target_core_fabric_ops::get_task_tag to get the tag and %u to format it
- Adjust context]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
Diffstat (limited to 'include/target')
| -rw-r--r-- | include/target/target_core_base.h | 1 |
1 files changed, 1 insertions, 0 deletions
diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h index 5c755a85630b..8c80f4a95e92 100644 --- a/include/target/target_core_base.h +++ b/include/target/target_core_base.h @@ -536,6 +536,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 completion t_transport_stop_comp; |
