target: Obtain se_node_acl->acl_kref during get_initiator_node_acl
authorNicholas Bellinger <nab@linux-iscsi.org>
Fri, 8 Jan 2016 06:09:27 +0000 (22:09 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 12 Mar 2017 05:37:27 +0000 (06:37 +0100)
commit4a3c526ced412e509a5abc1ed500996b5e1f048b
tree592dda9b88ba4070dd86f3146ed829ed12d040a3
parentda259399e4874b3ba7a35040eb80ccb3656fe6cd
target: Obtain se_node_acl->acl_kref during get_initiator_node_acl

commit 21aaa23b0ebbd19334fa461370c03cbb076b3295 upstream.

This patch addresses a long standing race where obtaining
se_node_acl->acl_kref in __transport_register_session()
happens a bit too late, and leaves open the potential
for core_tpg_del_initiator_node_acl() to hit a NULL
pointer dereference.

Instead, take ->acl_kref in core_tpg_get_initiator_node_acl()
while se_portal_group->acl_node_mutex is held, and move the
final target_put_nacl() from transport_deregister_session()
into transport_free_session() so that fabric driver login
failure handling using the modern method to still work
as expected.

Also, update core_tpg_get_initiator_node_acl() to take
an extra reference for dynamically generated acls for
demo-mode, before returning to fabric caller.  Also
update iscsi-target sendtargets special case handling
to use target_tpg_has_node_acl() when checking if
demo_mode_discovery == true during discovery lookup.

Note the existing wait_for_completion(&acl->acl_free_comp)
in core_tpg_del_initiator_node_acl() does not change.

Cc: Sagi Grimberg <sagig@mellanox.com>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Hannes Reinecke <hare@suse.de>
Cc: Andy Grover <agrover@redhat.com>
Cc: Mike Christie <michaelc@cs.wisc.edu>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/target/iscsi/iscsi_target.c
drivers/target/target_core_tpg.c
drivers/target/target_core_transport.c
include/target/target_core_fabric.h