All of lore.kernel.org
 help / color / mirror / Atom feed
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	stable@vger.kernel.org, Rob Millner <rlm@daterainc.com>,
	Nicholas Bellinger <nab@linux-iscsi.org>
Subject: [PATCH 4.9 28/60] target: Fix multi-session dynamic se_node_acl double free OOPs
Date: Mon, 13 Feb 2017 05:04:00 -0800	[thread overview]
Message-ID: <20170213130336.950857614@linuxfoundation.org> (raw)
In-Reply-To: <20170213130333.057515084@linuxfoundation.org>

4.9-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Nicholas Bellinger <nab@linux-iscsi.org>

commit 01d4d673558985d9a118e1e05026633c3e2ade9b upstream.

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>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

---
 drivers/target/target_core_transport.c |   69 ++++++++++++++++++++-------------
 include/target/target_core_base.h      |    1 
 2 files changed, 44 insertions(+), 26 deletions(-)

--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -457,8 +457,20 @@ static void target_complete_nacl(struct
 {
 	struct se_node_acl *nacl = container_of(kref,
 				struct se_node_acl, acl_kref);
+	struct se_portal_group *se_tpg = nacl->se_tpg;
 
-	complete(&nacl->acl_free_comp);
+	if (!nacl->dynamic_stop) {
+		complete(&nacl->acl_free_comp);
+		return;
+	}
+
+	mutex_lock(&se_tpg->acl_node_mutex);
+	list_del(&nacl->acl_list);
+	mutex_unlock(&se_tpg->acl_node_mutex);
+
+	core_tpg_wait_for_nacl_pr_ref(nacl);
+	core_free_device_list_for_node(nacl, se_tpg);
+	kfree(nacl);
 }
 
 void target_put_nacl(struct se_node_acl *nacl)
@@ -499,12 +511,39 @@ EXPORT_SYMBOL(transport_deregister_sessi
 void transport_free_session(struct se_session *se_sess)
 {
 	struct se_node_acl *se_nacl = se_sess->se_node_acl;
+
 	/*
 	 * Drop the se_node_acl->nacl_kref obtained from within
 	 * core_tpg_get_initiator_node_acl().
 	 */
 	if (se_nacl) {
+		struct se_portal_group *se_tpg = se_nacl->se_tpg;
+		const struct target_core_fabric_ops *se_tfo = se_tpg->se_tpg_tfo;
+		unsigned long flags;
+
 		se_sess->se_node_acl = NULL;
+
+		/*
+		 * Also determine if we need to drop the extra ->cmd_kref if
+		 * it had been previously dynamically generated, and
+		 * the endpoint is not caching dynamic ACLs.
+		 */
+		mutex_lock(&se_tpg->acl_node_mutex);
+		if (se_nacl->dynamic_node_acl &&
+		    !se_tfo->tpg_check_demo_mode_cache(se_tpg)) {
+			spin_lock_irqsave(&se_nacl->nacl_sess_lock, flags);
+			if (list_empty(&se_nacl->acl_sess_list))
+				se_nacl->dynamic_stop = true;
+			spin_unlock_irqrestore(&se_nacl->nacl_sess_lock, flags);
+
+			if (se_nacl->dynamic_stop)
+				list_del(&se_nacl->acl_list);
+		}
+		mutex_unlock(&se_tpg->acl_node_mutex);
+
+		if (se_nacl->dynamic_stop)
+			target_put_nacl(se_nacl);
+
 		target_put_nacl(se_nacl);
 	}
 	if (se_sess->sess_cmd_map) {
@@ -518,16 +557,12 @@ EXPORT_SYMBOL(transport_free_session);
 void transport_deregister_session(struct se_session *se_sess)
 {
 	struct se_portal_group *se_tpg = se_sess->se_tpg;
-	const struct target_core_fabric_ops *se_tfo;
-	struct se_node_acl *se_nacl;
 	unsigned long flags;
-	bool drop_nacl = false;
 
 	if (!se_tpg) {
 		transport_free_session(se_sess);
 		return;
 	}
-	se_tfo = se_tpg->se_tpg_tfo;
 
 	spin_lock_irqsave(&se_tpg->session_lock, flags);
 	list_del(&se_sess->sess_list);
@@ -535,33 +570,15 @@ void transport_deregister_session(struct
 	se_sess->fabric_sess_ptr = NULL;
 	spin_unlock_irqrestore(&se_tpg->session_lock, flags);
 
-	/*
-	 * Determine if we need to do extra work for this initiator node's
-	 * struct se_node_acl if it had been previously dynamically generated.
-	 */
-	se_nacl = se_sess->se_node_acl;
-
-	mutex_lock(&se_tpg->acl_node_mutex);
-	if (se_nacl && se_nacl->dynamic_node_acl) {
-		if (!se_tfo->tpg_check_demo_mode_cache(se_tpg)) {
-			list_del(&se_nacl->acl_list);
-			drop_nacl = true;
-		}
-	}
-	mutex_unlock(&se_tpg->acl_node_mutex);
-
-	if (drop_nacl) {
-		core_tpg_wait_for_nacl_pr_ref(se_nacl);
-		core_free_device_list_for_node(se_nacl, se_tpg);
-		se_sess->se_node_acl = NULL;
-		kfree(se_nacl);
-	}
 	pr_debug("TARGET_CORE[%s]: Deregistered fabric_sess\n",
 		se_tpg->se_tpg_tfo->get_fabric_name());
 	/*
 	 * If last kref is dropping now for an explicit NodeACL, awake sleeping
 	 * ->acl_free_comp caller to wakeup configfs se_node_acl->acl_group
 	 * removal context from within transport_free_session() code.
+	 *
+	 * For dynamic ACL, target_put_nacl() uses target_complete_nacl()
+	 * to release all remaining generate_node_acl=1 created ACL resources.
 	 */
 
 	transport_free_session(se_sess);
--- a/include/target/target_core_base.h
+++ b/include/target/target_core_base.h
@@ -538,6 +538,7 @@ struct se_node_acl {
 	char			initiatorname[TRANSPORT_IQN_LEN];
 	/* Used to signal demo mode created ACL, disabled by default */
 	bool			dynamic_node_acl;
+	bool			dynamic_stop;
 	u32			queue_depth;
 	u32			acl_index;
 	enum target_prot_type	saved_prot_type;

  parent reply	other threads:[~2017-02-13 13:20 UTC|newest]

Thread overview: 64+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-02-13 13:03 [PATCH 4.9 00/60] 4.9.10-stable review Greg Kroah-Hartman
2017-02-13 13:03 ` [PATCH 4.9 01/60] cpufreq: intel_pstate: Disable energy efficiency optimization Greg Kroah-Hartman
2017-02-13 13:03 ` [PATCH 4.9 02/60] acpi, nfit: fix acpi_nfit_flush_probe() crash Greg Kroah-Hartman
2017-02-13 13:03 ` [PATCH 4.9 03/60] libnvdimm, namespace: do not delete namespace-id 0 Greg Kroah-Hartman
2017-02-13 13:03 ` [PATCH 4.9 04/60] libnvdimm, pfn: fix memmap reservation size versus 4K alignment Greg Kroah-Hartman
2017-02-13 13:03 ` [PATCH 4.9 05/60] dm rq: cope with DM device destruction while in dm_old_request_fn() Greg Kroah-Hartman
2017-02-13 13:03 ` [PATCH 4.9 07/60] crypto: chcr - Check device is allocated before use Greg Kroah-Hartman
2017-02-13 13:03 ` [PATCH 4.9 08/60] crypto: qat - fix bar discovery for c62x Greg Kroah-Hartman
2017-02-13 13:03 ` [PATCH 4.9 09/60] crypto: qat - zero esram only for DH85x devices Greg Kroah-Hartman
2017-02-13 13:03 ` [PATCH 4.9 10/60] crypto: ccp - Fix DMA operations when IOMMU is enabled Greg Kroah-Hartman
2017-02-13 13:03 ` [PATCH 4.9 11/60] crypto: ccp - Fix double add when creating new DMA command Greg Kroah-Hartman
2017-02-13 13:03 ` [PATCH 4.9 12/60] ARC: [arcompact] brown paper bag bug in unaligned access delay slot fixup Greg Kroah-Hartman
2017-02-13 13:03   ` Greg Kroah-Hartman
2017-02-13 13:03 ` [PATCH 4.9 13/60] Input: uinput - fix crash when mixing old and new init style Greg Kroah-Hartman
2017-02-13 13:03 ` [PATCH 4.9 14/60] selinux: fix off-by-one in setprocattr Greg Kroah-Hartman
2017-02-13 13:03 ` [PATCH 4.9 15/60] Revert "x86/ioapic: Restore IO-APIC irq_chip retrigger callback" Greg Kroah-Hartman
2017-02-13 13:03 ` [PATCH 4.9 16/60] rtlwifi: rtl8192ce: Fix loading of incorrect firmware Greg Kroah-Hartman
2017-02-13 13:03 ` [PATCH 4.9 17/60] cpumask: use nr_cpumask_bits for parsing functions Greg Kroah-Hartman
2017-02-13 13:03 ` [PATCH 4.9 18/60] mm/slub.c: fix random_seq offset destruction Greg Kroah-Hartman
2017-02-13 13:03 ` [PATCH 4.9 19/60] ibmvscsis: Add SGL limit Greg Kroah-Hartman
2017-02-13 13:03 ` [PATCH 4.9 20/60] hns: avoid stack overflow with CONFIG_KASAN Greg Kroah-Hartman
2017-02-13 13:03 ` [PATCH 4.9 21/60] ARM: 8643/3: arm/ptrace: Preserve previous registers for short regset write Greg Kroah-Hartman
2017-02-13 13:03 ` [PATCH 4.9 22/60] drm/i915: fix use-after-free in page_flip_completed() Greg Kroah-Hartman
2017-02-13 13:03 ` [PATCH 4.9 23/60] drm/i915/bxt: Add MST support when do DPLL calculation Greg Kroah-Hartman
2017-02-13 13:03 ` [PATCH 4.9 24/60] drm/atomic: Fix double free in drm_atomic_state_default_clear Greg Kroah-Hartman
2017-02-13 13:03 ` [PATCH 4.9 25/60] target: Dont BUG_ON during NodeACL dynamic -> explicit conversion Greg Kroah-Hartman
2017-02-13 13:03 ` [PATCH 4.9 26/60] target: Use correct SCSI status during EXTENDED_COPY exception Greg Kroah-Hartman
2017-02-13 13:03 ` [PATCH 4.9 27/60] target: Fix early transport_generic_handle_tmr abort scenario Greg Kroah-Hartman
2017-02-13 13:04 ` Greg Kroah-Hartman [this message]
2017-02-13 13:04 ` [PATCH 4.9 29/60] target: Fix COMPARE_AND_WRITE ref leak for non GOOD status Greg Kroah-Hartman
2017-02-13 13:04 ` [PATCH 4.9 31/60] ARM: 8642/1: LPAE: catch pending imprecise abort on unmask Greg Kroah-Hartman
2017-02-13 13:04   ` Greg Kroah-Hartman
2017-02-13 13:04 ` [PATCH 4.9 33/60] nl80211: Fix mesh HT operation check Greg Kroah-Hartman
2017-02-13 13:04 ` [PATCH 4.9 34/60] mac80211: Fix adding of mesh vendor IEs Greg Kroah-Hartman
2017-02-13 13:04 ` [PATCH 4.9 35/60] net/mlx5e: Modify TIRs hash only when its needed Greg Kroah-Hartman
2017-02-13 13:04 ` [PATCH 4.9 36/60] Drivers: hv: vmbus: Base host signaling strictly on the ring state Greg Kroah-Hartman
2017-02-13 13:04 ` [PATCH 4.9 37/60] Drivers: hv: vmbus: On write cleanup the logic to interrupt the host Greg Kroah-Hartman
2017-02-13 13:04 ` [PATCH 4.9 38/60] Drivers: hv: vmbus: On the read path " Greg Kroah-Hartman
2017-02-13 13:04 ` [PATCH 4.9 39/60] Drivers: hv: vmbus: finally fix hv_need_to_signal_on_read() Greg Kroah-Hartman
2017-02-13 13:04 ` [PATCH 4.9 40/60] scsi: zfcp: fix use-after-free by not tracing WKA port open/close on failed send Greg Kroah-Hartman
2017-02-13 13:04 ` [PATCH 4.9 41/60] scsi: aacraid: Fix INTx/MSI-x issue with older controllers Greg Kroah-Hartman
2017-02-13 13:04 ` [PATCH 4.9 42/60] scsi: mpt3sas: disable ASPM for MPI2 controllers Greg Kroah-Hartman
2017-02-13 13:04 ` [PATCH 4.9 43/60] scsi: qla2xxx: Avoid that issuing a LIP triggers a kernel crash Greg Kroah-Hartman
2017-02-13 13:04 ` [PATCH 4.9 44/60] btrfs: fix btrfs_compat_ioctl failures on non-compat ioctls Greg Kroah-Hartman
2017-02-13 13:04 ` [PATCH 4.9 45/60] powerpc/mm/radix: Update ERAT flushes when invalidating TLB Greg Kroah-Hartman
2017-02-13 13:04 ` [PATCH 4.9 46/60] powerpc/powernv: Fix CPU hotplug to handle waking on HVI Greg Kroah-Hartman
2017-02-13 13:04 ` [PATCH 4.9 47/60] xen-netfront: Delete rx_refill_timer in xennet_disconnect_backend() Greg Kroah-Hartman
2017-02-13 13:04 ` [PATCH 4.9 48/60] ALSA: hda - adding a new NV HDMI/DP codec ID in the driver Greg Kroah-Hartman
2017-02-13 13:04 ` [PATCH 4.9 49/60] ALSA: seq: Fix race at creating a queue Greg Kroah-Hartman
2017-02-13 13:04 ` [PATCH 4.9 50/60] ALSA: seq: Dont handle loop timeout at snd_seq_pool_done() Greg Kroah-Hartman
2017-02-13 13:04 ` [PATCH 4.9 51/60] Revert "ALSA: line6: Only determine control port properties if needed" Greg Kroah-Hartman
2017-02-13 13:04 ` [PATCH 4.9 52/60] x86/mm/ptdump: Fix soft lockup in page table walker Greg Kroah-Hartman
2017-02-13 13:04 ` [PATCH 4.9 53/60] x86/CPU/AMD: Bring back Compute Unit ID Greg Kroah-Hartman
2017-02-13 13:04 ` [PATCH 4.9 54/60] x86/CPU/AMD: Fix Zen SMT topology Greg Kroah-Hartman
2017-02-13 13:04 ` [PATCH 4.9 55/60] IB/rxe: Fix resid update Greg Kroah-Hartman
2017-02-13 13:04 ` [PATCH 4.9 56/60] IB/rxe: Fix mem_check_range integer overflow Greg Kroah-Hartman
2017-02-13 13:04 ` [PATCH 4.9 57/60] stacktrace, lockdep: Fix address, newline ugliness Greg Kroah-Hartman
2017-02-13 13:04 ` [PATCH 4.9 58/60] perf diff: Fix -o/--order option behavior (again) Greg Kroah-Hartman
2017-02-13 13:04 ` [PATCH 4.9 59/60] perf diff: Fix segfault on perf diff -o N option Greg Kroah-Hartman
2017-02-13 13:04 ` [PATCH 4.9 60/60] perf/core: Fix crash in perf_event_read() Greg Kroah-Hartman
2017-02-13 17:09 ` [PATCH 4.9 00/60] 4.9.10-stable review Shuah Khan
2017-02-13 17:24   ` Greg Kroah-Hartman
2017-02-13 20:03 ` Guenter Roeck
2017-02-14 22:54   ` Greg Kroah-Hartman

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20170213130336.950857614@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=nab@linux-iscsi.org \
    --cc=rlm@daterainc.com \
    --cc=stable@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.