diff options
author | Bart Van Assche <bvanassche@acm.org> | 2018-11-27 15:51:58 -0800 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2019-01-26 09:32:38 +0100 |
commit | 3ad8148ce042a82ccfff6d629a60aa221f0e012e (patch) | |
tree | 34a235e9eac48367165f99c5c2fdec63b9b00dbd /include/target | |
parent | 25d3546acd60cf1898dd75f16d1e1b78b23be270 (diff) | |
download | linux-rpi3-3ad8148ce042a82ccfff6d629a60aa221f0e012e.tar.gz linux-rpi3-3ad8148ce042a82ccfff6d629a60aa221f0e012e.tar.bz2 linux-rpi3-3ad8148ce042a82ccfff6d629a60aa221f0e012e.zip |
scsi: target/core: Make sure that target_wait_for_sess_cmds() waits long enough
[ Upstream commit ad669505c4e9db9af9faeb5c51aa399326a80d91 ]
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>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'include/target')
-rw-r--r-- | include/target/target_core_base.h | 1 | ||||
-rw-r--r-- | include/target/target_core_fabric.h | 2 |
2 files changed, 2 insertions, 1 deletions
diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h index 7a4ee7852ca4..2cfd3b4573b0 100644 --- a/include/target/target_core_base.h +++ b/include/target/target_core_base.h @@ -602,6 +602,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 f4147b398431..eb9d0923c55c 100644 --- a/include/target/target_core_fabric.h +++ b/include/target/target_core_fabric.h @@ -116,7 +116,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); |