target: Fix multi-session dynamic se_node_acl double free OOPs
authorNicholas Bellinger <nab@linux-iscsi.org>
Wed, 7 Dec 2016 20:55:54 +0000 (12:55 -0800)
committerNicholas Bellinger <nab@linux-iscsi.org>
Wed, 8 Feb 2017 16:25:23 +0000 (08:25 -0800)
commit01d4d673558985d9a118e1e05026633c3e2ade9b
tree0aa259773374b5a919689c9db28d78274778b359
parentc54eeffbe9338fa982dc853d816fda9202a13b5a
target: Fix multi-session dynamic se_node_acl double free OOPs

This patch addresses a long-standing bug with multi-session
(eg: iscsi-target + iser-target) se_node_acl dynamic free
withini transport_deregister_session().

This bug is caused when a storage endpoint is configured with
demo-mode (generate_node_acls = 1 + cache_dynamic_acls = 1)
initiators, and initiator login creates a new dynamic node acl
and attaches two sessions to it.

After that, demo-mode for the storage instance is disabled via
configfs (generate_node_acls = 0 + cache_dynamic_acls = 0) and
the existing dynamic acl is never converted to an explicit ACL.

The end result is dynamic acl resources are released twice when
the sessions are shutdown in transport_deregister_session().

If the storage instance is not changed to disable demo-mode,
or the dynamic acl is converted to an explict ACL, or there
is only a single session associated with the dynamic ACL,
the bug is not triggered.

To address this big, move the release of dynamic se_node_acl
memory into target_complete_nacl() so it's only freed once
when se_node_acl->acl_kref reaches zero.

(Drop unnecessary list_del_init usage - HCH)

Reported-by: Rob Millner <rlm@daterainc.com>
Tested-by: Rob Millner <rlm@daterainc.com>
Cc: Rob Millner <rlm@daterainc.com>
Cc: stable@vger.kernel.org # 4.1+
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
drivers/target/target_core_transport.c
include/target/target_core_base.h