stable.vger.kernel.org archive mirror
 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, Vishal Verma <vishal.l.verma@intel.com>,
	Dan Williams <dan.j.williams@intel.com>,
	Sasha Levin <sashal@kernel.org>
Subject: [PATCH 4.19 07/45] libnvdimm/bus: Prepare the nd_ioctl() path to be re-entrant
Date: Thu,  8 Aug 2019 21:04:53 +0200	[thread overview]
Message-ID: <20190808190454.189996943@linuxfoundation.org> (raw)
In-Reply-To: <20190808190453.827571908@linuxfoundation.org>

commit 6de5d06e657acdbcf9637dac37916a4a5309e0f4 upstream.

In preparation for not holding a lock over the execution of nd_ioctl(),
update the implementation to allow multiple threads to be attempting
ioctls at the same time. The bus lock still prevents multiple in-flight
->ndctl() invocations from corrupting each other's state, but static
global staging buffers are moved to the heap.

Reported-by: Vishal Verma <vishal.l.verma@intel.com>
Reviewed-by: Vishal Verma <vishal.l.verma@intel.com>
Tested-by: Vishal Verma <vishal.l.verma@intel.com>
Link: https://lore.kernel.org/r/156341208947.292348.10560140326807607481.stgit@dwillia2-desk3.amr.corp.intel.com
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/nvdimm/bus.c | 59 +++++++++++++++++++++++++++-----------------
 1 file changed, 37 insertions(+), 22 deletions(-)

diff --git a/drivers/nvdimm/bus.c b/drivers/nvdimm/bus.c
index 11cfd23e5aff7..5abcdb4faa644 100644
--- a/drivers/nvdimm/bus.c
+++ b/drivers/nvdimm/bus.c
@@ -951,20 +951,19 @@ static int __nd_ioctl(struct nvdimm_bus *nvdimm_bus, struct nvdimm *nvdimm,
 		int read_only, unsigned int ioctl_cmd, unsigned long arg)
 {
 	struct nvdimm_bus_descriptor *nd_desc = nvdimm_bus->nd_desc;
-	static char out_env[ND_CMD_MAX_ENVELOPE];
-	static char in_env[ND_CMD_MAX_ENVELOPE];
 	const struct nd_cmd_desc *desc = NULL;
 	unsigned int cmd = _IOC_NR(ioctl_cmd);
 	struct device *dev = &nvdimm_bus->dev;
 	void __user *p = (void __user *) arg;
+	char *out_env = NULL, *in_env = NULL;
 	const char *cmd_name, *dimm_name;
 	u32 in_len = 0, out_len = 0;
 	unsigned int func = cmd;
 	unsigned long cmd_mask;
 	struct nd_cmd_pkg pkg;
 	int rc, i, cmd_rc;
+	void *buf = NULL;
 	u64 buf_len = 0;
-	void *buf;
 
 	if (nvdimm) {
 		desc = nd_cmd_dimm_desc(cmd);
@@ -1004,6 +1003,9 @@ static int __nd_ioctl(struct nvdimm_bus *nvdimm_bus, struct nvdimm *nvdimm,
 		}
 
 	/* process an input envelope */
+	in_env = kzalloc(ND_CMD_MAX_ENVELOPE, GFP_KERNEL);
+	if (!in_env)
+		return -ENOMEM;
 	for (i = 0; i < desc->in_num; i++) {
 		u32 in_size, copy;
 
@@ -1011,14 +1013,17 @@ static int __nd_ioctl(struct nvdimm_bus *nvdimm_bus, struct nvdimm *nvdimm,
 		if (in_size == UINT_MAX) {
 			dev_err(dev, "%s:%s unknown input size cmd: %s field: %d\n",
 					__func__, dimm_name, cmd_name, i);
-			return -ENXIO;
+			rc = -ENXIO;
+			goto out;
 		}
-		if (in_len < sizeof(in_env))
-			copy = min_t(u32, sizeof(in_env) - in_len, in_size);
+		if (in_len < ND_CMD_MAX_ENVELOPE)
+			copy = min_t(u32, ND_CMD_MAX_ENVELOPE - in_len, in_size);
 		else
 			copy = 0;
-		if (copy && copy_from_user(&in_env[in_len], p + in_len, copy))
-			return -EFAULT;
+		if (copy && copy_from_user(&in_env[in_len], p + in_len, copy)) {
+			rc = -EFAULT;
+			goto out;
+		}
 		in_len += in_size;
 	}
 
@@ -1030,6 +1035,12 @@ static int __nd_ioctl(struct nvdimm_bus *nvdimm_bus, struct nvdimm *nvdimm,
 	}
 
 	/* process an output envelope */
+	out_env = kzalloc(ND_CMD_MAX_ENVELOPE, GFP_KERNEL);
+	if (!out_env) {
+		rc = -ENOMEM;
+		goto out;
+	}
+
 	for (i = 0; i < desc->out_num; i++) {
 		u32 out_size = nd_cmd_out_size(nvdimm, cmd, desc, i,
 				(u32 *) in_env, (u32 *) out_env, 0);
@@ -1038,15 +1049,18 @@ static int __nd_ioctl(struct nvdimm_bus *nvdimm_bus, struct nvdimm *nvdimm,
 		if (out_size == UINT_MAX) {
 			dev_dbg(dev, "%s unknown output size cmd: %s field: %d\n",
 					dimm_name, cmd_name, i);
-			return -EFAULT;
+			rc = -EFAULT;
+			goto out;
 		}
-		if (out_len < sizeof(out_env))
-			copy = min_t(u32, sizeof(out_env) - out_len, out_size);
+		if (out_len < ND_CMD_MAX_ENVELOPE)
+			copy = min_t(u32, ND_CMD_MAX_ENVELOPE - out_len, out_size);
 		else
 			copy = 0;
 		if (copy && copy_from_user(&out_env[out_len],
-					p + in_len + out_len, copy))
-			return -EFAULT;
+					p + in_len + out_len, copy)) {
+			rc = -EFAULT;
+			goto out;
+		}
 		out_len += out_size;
 	}
 
@@ -1054,12 +1068,15 @@ static int __nd_ioctl(struct nvdimm_bus *nvdimm_bus, struct nvdimm *nvdimm,
 	if (buf_len > ND_IOCTL_MAX_BUFLEN) {
 		dev_dbg(dev, "%s cmd: %s buf_len: %llu > %d\n", dimm_name,
 				cmd_name, buf_len, ND_IOCTL_MAX_BUFLEN);
-		return -EINVAL;
+		rc = -EINVAL;
+		goto out;
 	}
 
 	buf = vmalloc(buf_len);
-	if (!buf)
-		return -ENOMEM;
+	if (!buf) {
+		rc = -ENOMEM;
+		goto out;
+	}
 
 	if (copy_from_user(buf, p, buf_len)) {
 		rc = -EFAULT;
@@ -1081,17 +1098,15 @@ static int __nd_ioctl(struct nvdimm_bus *nvdimm_bus, struct nvdimm *nvdimm,
 		nvdimm_account_cleared_poison(nvdimm_bus, clear_err->address,
 				clear_err->cleared);
 	}
-	nvdimm_bus_unlock(&nvdimm_bus->dev);
 
 	if (copy_to_user(p, buf, buf_len))
 		rc = -EFAULT;
 
-	vfree(buf);
-	return rc;
-
- out_unlock:
+out_unlock:
 	nvdimm_bus_unlock(&nvdimm_bus->dev);
- out:
+out:
+	kfree(in_env);
+	kfree(out_env);
 	vfree(buf);
 	return rc;
 }
-- 
2.20.1




  parent reply	other threads:[~2019-08-08 19:14 UTC|newest]

Thread overview: 52+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-08-08 19:04 [PATCH 4.19 00/45] 4.19.66-stable review Greg Kroah-Hartman
2019-08-08 19:04 ` [PATCH 4.19 01/45] scsi: fcoe: Embed fc_rport_priv in fcoe_rport structure Greg Kroah-Hartman
2019-08-08 19:04 ` [PATCH 4.19 02/45] gcc-9: dont warn about uninitialized variable Greg Kroah-Hartman
2019-08-08 19:04 ` [PATCH 4.19 03/45] driver core: Establish order of operations for device_add and device_del via bitflag Greg Kroah-Hartman
2019-08-08 19:04 ` [PATCH 4.19 04/45] drivers/base: Introduce kill_device() Greg Kroah-Hartman
2019-08-08 19:04 ` [PATCH 4.19 05/45] libnvdimm/bus: Prevent duplicate device_unregister() calls Greg Kroah-Hartman
2019-08-08 19:04 ` [PATCH 4.19 06/45] libnvdimm/region: Register badblocks before namespaces Greg Kroah-Hartman
2019-08-08 19:04 ` Greg Kroah-Hartman [this message]
2019-08-08 19:04 ` [PATCH 4.19 08/45] libnvdimm/bus: Fix wait_nvdimm_bus_probe_idle() ABBA deadlock Greg Kroah-Hartman
2019-08-08 19:04 ` [PATCH 4.19 09/45] HID: wacom: fix bit shift for Cintiq Companion 2 Greg Kroah-Hartman
2019-08-08 19:04 ` [PATCH 4.19 10/45] HID: Add quirk for HP X1200 PIXART OEM mouse Greg Kroah-Hartman
2019-08-08 19:04 ` [PATCH 4.19 11/45] [PATCH] IB: directly cast the sockaddr union to aockaddr Greg Kroah-Hartman
2019-08-08 19:04 ` [PATCH 4.19 12/45] atm: iphase: Fix Spectre v1 vulnerability Greg Kroah-Hartman
2019-08-08 19:04 ` [PATCH 4.19 13/45] bnx2x: Disable multi-cos feature Greg Kroah-Hartman
2019-08-08 19:05 ` [PATCH 4.19 14/45] ife: error out when nla attributes are empty Greg Kroah-Hartman
2019-08-08 19:05 ` [PATCH 4.19 15/45] ip6_gre: reload ipv6h in prepare_ip6gre_xmit_ipv6 Greg Kroah-Hartman
2019-08-08 19:05 ` [PATCH 4.19 16/45] ip6_tunnel: fix possible use-after-free on xmit Greg Kroah-Hartman
2019-08-08 19:05 ` [PATCH 4.19 17/45] ipip: validate header length in ipip_tunnel_xmit Greg Kroah-Hartman
2019-08-08 19:05 ` [PATCH 4.19 18/45] mlxsw: spectrum: Fix error path in mlxsw_sp_module_init() Greg Kroah-Hartman
2019-08-08 19:05 ` [PATCH 4.19 19/45] mvpp2: fix panic on module removal Greg Kroah-Hartman
2019-08-08 19:05 ` [PATCH 4.19 20/45] mvpp2: refactor MTU change code Greg Kroah-Hartman
2019-08-08 19:05 ` [PATCH 4.19 21/45] net: bridge: delete local fdb on device init failure Greg Kroah-Hartman
2019-08-08 19:05 ` [PATCH 4.19 22/45] net: bridge: mcast: dont delete permanent entries when fast leave is enabled Greg Kroah-Hartman
2019-08-08 19:05 ` [PATCH 4.19 23/45] net: fix ifindex collision during namespace removal Greg Kroah-Hartman
2019-08-08 19:05 ` [PATCH 4.19 24/45] net/mlx5e: always initialize frag->last_in_page Greg Kroah-Hartman
2019-08-08 19:05 ` [PATCH 4.19 25/45] net/mlx5: Use reversed order when unregister devices Greg Kroah-Hartman
2019-08-08 19:05 ` [PATCH 4.19 26/45] net: phylink: Fix flow control for fixed-link Greg Kroah-Hartman
2019-08-08 19:05 ` [PATCH 4.19 27/45] net: qualcomm: rmnet: Fix incorrect UL checksum offload logic Greg Kroah-Hartman
2019-08-08 19:05 ` [PATCH 4.19 28/45] net: sched: Fix a possible null-pointer dereference in dequeue_func() Greg Kroah-Hartman
2019-08-08 19:05 ` [PATCH 4.19 29/45] net sched: update vlan action for batched events operations Greg Kroah-Hartman
2019-08-08 19:05 ` [PATCH 4.19 30/45] net: sched: use temporary variable for actions indexes Greg Kroah-Hartman
2019-08-08 19:05 ` [PATCH 4.19 31/45] net/smc: do not schedule tx_work in SMC_CLOSED state Greg Kroah-Hartman
2019-08-08 19:05 ` [PATCH 4.19 32/45] NFC: nfcmrvl: fix gpio-handling regression Greg Kroah-Hartman
2019-08-08 19:05 ` [PATCH 4.19 33/45] ocelot: Cancel delayed work before wq destruction Greg Kroah-Hartman
2019-08-08 19:05 ` [PATCH 4.19 34/45] tipc: compat: allow tipc commands without arguments Greg Kroah-Hartman
2019-08-08 19:05 ` [PATCH 4.19 35/45] tun: mark small packets as owned by the tap sock Greg Kroah-Hartman
2019-08-08 19:05 ` [PATCH 4.19 36/45] net/mlx5: Fix modify_cq_in alignment Greg Kroah-Hartman
2019-08-10 11:25   ` Pavel Machek
2019-08-11  6:17     ` Leon Romanovsky
2019-08-08 19:05 ` [PATCH 4.19 37/45] net/mlx5e: Prevent encap flow counter update async to user query Greg Kroah-Hartman
2019-08-08 19:05 ` [PATCH 4.19 38/45] r8169: dont use MSI before RTL8168d Greg Kroah-Hartman
2019-08-08 19:05 ` [PATCH 4.19 39/45] compat_ioctl: pppoe: fix PPPOEIOCSFWD handling Greg Kroah-Hartman
2019-08-08 19:05 ` [PATCH 4.19 40/45] cgroup: Call cgroup_release() before __exit_signal() Greg Kroah-Hartman
2019-08-08 19:05 ` [PATCH 4.19 41/45] cgroup: Implement css_task_iter_skip() Greg Kroah-Hartman
2019-08-08 19:05 ` [PATCH 4.19 42/45] cgroup: Include dying leaders with live threads in PROCS iterations Greg Kroah-Hartman
2019-08-08 19:05 ` [PATCH 4.19 43/45] cgroup: css_task_iter_skip()d iterators must be advanced before accessed Greg Kroah-Hartman
2019-08-08 19:05 ` [PATCH 4.19 44/45] cgroup: Fix css_task_iter_advance_css_set() cset skip condition Greg Kroah-Hartman
2019-08-08 19:05 ` [PATCH 4.19 45/45] spi: bcm2835: Fix 3-wire mode if DMA is enabled Greg Kroah-Hartman
2019-08-09  0:37 ` [PATCH 4.19 00/45] 4.19.66-stable review shuah
2019-08-09  3:20 ` Naresh Kamboju
2019-08-09 14:49 ` Thierry Reding
2019-08-09 15:37 ` Guenter Roeck

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=20190808190454.189996943@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=dan.j.williams@intel.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=sashal@kernel.org \
    --cc=stable@vger.kernel.org \
    --cc=vishal.l.verma@intel.com \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).