summaryrefslogtreecommitdiff
path: root/include/target
diff options
context:
space:
mode:
authorBart Van Assche <bvanassche@acm.org>2018-11-27 15:51:58 -0800
committerMartin K. Petersen <martin.petersen@oracle.com>2018-12-07 21:20:07 -0500
commitad669505c4e9db9af9faeb5c51aa399326a80d91 (patch)
treedafa06323672f2c181781a0a59e40e43e71dfa4b /include/target
parenta95be3842c51c9ac32fe17faedf2c156ccf81bd7 (diff)
downloadlwn-ad669505c4e9db9af9faeb5c51aa399326a80d91.tar.gz
lwn-ad669505c4e9db9af9faeb5c51aa399326a80d91.zip
scsi: target/core: Make sure that target_wait_for_sess_cmds() waits long enough
A session must only be released after all code that accesses the session structure has finished. Make sure that this is the case by introducing a new command counter per session that is only decremented after the .release_cmd() callback has finished. This patch fixes the following crash: BUG: KASAN: use-after-free in do_raw_spin_lock+0x1c/0x130 Read of size 4 at addr ffff8801534b16e4 by task rmdir/14805 CPU: 16 PID: 14805 Comm: rmdir Not tainted 4.18.0-rc2-dbg+ #5 Call Trace: dump_stack+0xa4/0xf5 print_address_description+0x6f/0x270 kasan_report+0x241/0x360 __asan_load4+0x78/0x80 do_raw_spin_lock+0x1c/0x130 _raw_spin_lock_irqsave+0x52/0x60 srpt_set_ch_state+0x27/0x70 [ib_srpt] srpt_disconnect_ch+0x1b/0xc0 [ib_srpt] srpt_close_session+0xa8/0x260 [ib_srpt] target_shutdown_sessions+0x170/0x180 [target_core_mod] core_tpg_del_initiator_node_acl+0xf3/0x200 [target_core_mod] target_fabric_nacl_base_release+0x25/0x30 [target_core_mod] config_item_release+0x9c/0x110 [configfs] config_item_put+0x26/0x30 [configfs] configfs_rmdir+0x3b8/0x510 [configfs] vfs_rmdir+0xb3/0x1e0 do_rmdir+0x262/0x2c0 do_syscall_64+0x77/0x230 entry_SYSCALL_64_after_hwframe+0x49/0xbe Cc: Nicholas Bellinger <nab@linux-iscsi.org> Cc: Mike Christie <mchristi@redhat.com> Cc: Christoph Hellwig <hch@lst.de> Cc: David Disseldorp <ddiss@suse.de> Cc: Hannes Reinecke <hare@suse.de> Signed-off-by: Bart Van Assche <bvanassche@acm.org> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'include/target')
-rw-r--r--include/target/target_core_base.h1
-rw-r--r--include/target/target_core_fabric.h2
2 files changed, 2 insertions, 1 deletions
diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h
index bb965a355187..6e34ec4df6b7 100644
--- a/include/target/target_core_base.h
+++ b/include/target/target_core_base.h
@@ -603,6 +603,7 @@ struct se_session {
struct se_node_acl *se_node_acl;
struct se_portal_group *se_tpg;
void *fabric_sess_ptr;
+ struct percpu_ref cmd_count;
struct list_head sess_list;
struct list_head sess_acl_list;
struct list_head sess_cmd_list;
diff --git a/include/target/target_core_fabric.h b/include/target/target_core_fabric.h
index 0a1595f3c5a1..3b81a5b01497 100644
--- a/include/target/target_core_fabric.h
+++ b/include/target/target_core_fabric.h
@@ -126,7 +126,7 @@ struct se_session *target_setup_session(struct se_portal_group *,
struct se_session *, void *));
void target_remove_session(struct se_session *);
-void transport_init_session(struct se_session *);
+int transport_init_session(struct se_session *se_sess);
struct se_session *transport_alloc_session(enum target_prot_op);
int transport_alloc_session_tags(struct se_session *, unsigned int,
unsigned int);