Home Home > GIT Browse > stable
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJiri Slaby <jslaby@suse.cz>2019-08-16 22:01:45 +0200
committerJiri Slaby <jslaby@suse.cz>2019-08-16 22:25:10 +0200
commit2b8ce587a8a52cbf353c24528766725595f0fae9 (patch)
treee616d04575a1985c62bab5e1d079a4f7ee9affff
parent1be9b9b58d203a604fe5b3b6f188f04cada39362 (diff)
nvme: fix memory leak caused by incorrect subsystem free
-rw-r--r--patches.kernel.org/5.2.9-104-nvme-fix-memory-leak-caused-by-incorrect-subsys.patch90
-rw-r--r--series.conf1
2 files changed, 91 insertions, 0 deletions
diff --git a/patches.kernel.org/5.2.9-104-nvme-fix-memory-leak-caused-by-incorrect-subsys.patch b/patches.kernel.org/5.2.9-104-nvme-fix-memory-leak-caused-by-incorrect-subsys.patch
new file mode 100644
index 0000000000..59e009cb03
--- /dev/null
+++ b/patches.kernel.org/5.2.9-104-nvme-fix-memory-leak-caused-by-incorrect-subsys.patch
@@ -0,0 +1,90 @@
+From: Logan Gunthorpe <logang@deltatee.com>
+Date: Thu, 18 Jul 2019 17:53:50 -0600
+Subject: [PATCH] nvme: fix memory leak caused by incorrect subsystem free
+References: bnc#1012628
+Patch-mainline: 5.2.9
+Git-commit: e654dfd38c1ecf58d8d019f3c053189413484a5b
+
+[ Upstream commit e654dfd38c1ecf58d8d019f3c053189413484a5b ]
+
+When freeing the subsystem after finding another match with
+__nvme_find_get_subsystem(), use put_device() instead of
+__nvme_release_subsystem() which calls kfree() directly.
+
+Per the documentation, put_device() should always be used
+after device_initialization() is called. Otherwise, leaks
+like the one below which was detected by kmemleak may occur.
+
+Once the call of __nvme_release_subsystem() is removed it no
+longer makes sense to keep the helper, so fold it back
+into nvme_release_subsystem().
+
+unreferenced object 0xffff8883d12bfbc0 (size 16):
+ comm "nvme", pid 2635, jiffies 4294933602 (age 739.952s)
+ hex dump (first 16 bytes):
+ 6e 76 6d 65 2d 73 75 62 73 79 73 32 00 88 ff ff nvme-subsys2....
+ backtrace:
+ [<000000007d8fc208>] __kmalloc_track_caller+0x16d/0x2a0
+ [<0000000081169e5f>] kvasprintf+0xad/0x130
+ [<0000000025626f25>] kvasprintf_const+0x47/0x120
+ [<00000000fa66ad36>] kobject_set_name_vargs+0x44/0x120
+ [<000000004881f8b3>] dev_set_name+0x98/0xc0
+ [<000000007124dae3>] nvme_init_identify+0x1995/0x38e0
+ [<000000009315020a>] nvme_loop_configure_admin_queue+0x4fa/0x5e0
+ [<000000001a63e766>] nvme_loop_create_ctrl+0x489/0xf80
+ [<00000000a46ecc23>] nvmf_dev_write+0x1a12/0x2220
+ [<000000002259b3d5>] __vfs_write+0x66/0x120
+ [<000000002f6df81e>] vfs_write+0x154/0x490
+ [<000000007e8cfc19>] ksys_write+0x10a/0x240
+ [<00000000ff5c7b85>] __x64_sys_write+0x73/0xb0
+ [<00000000fee6d692>] do_syscall_64+0xaa/0x470
+ [<00000000997e1ede>] entry_SYSCALL_64_after_hwframe+0x49/0xbe
+
+Fixes: ab9e00cc72fa ("nvme: track subsystems")
+Signed-off-by: Logan Gunthorpe <logang@deltatee.com>
+Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+---
+ drivers/nvme/host/core.c | 12 +++++-------
+ 1 file changed, 5 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
+index 4a1d2ab4d161..5deb4deb3820 100644
+--- a/drivers/nvme/host/core.c
++++ b/drivers/nvme/host/core.c
+@@ -2264,17 +2264,15 @@ static void nvme_init_subnqn(struct nvme_subsystem *subsys, struct nvme_ctrl *ct
+ memset(subsys->subnqn + off, 0, sizeof(subsys->subnqn) - off);
+ }
+
+-static void __nvme_release_subsystem(struct nvme_subsystem *subsys)
++static void nvme_release_subsystem(struct device *dev)
+ {
++ struct nvme_subsystem *subsys =
++ container_of(dev, struct nvme_subsystem, dev);
++
+ ida_simple_remove(&nvme_subsystems_ida, subsys->instance);
+ kfree(subsys);
+ }
+
+-static void nvme_release_subsystem(struct device *dev)
+-{
+- __nvme_release_subsystem(container_of(dev, struct nvme_subsystem, dev));
+-}
+-
+ static void nvme_destroy_subsystem(struct kref *ref)
+ {
+ struct nvme_subsystem *subsys =
+@@ -2429,7 +2427,7 @@ static int nvme_init_subsystem(struct nvme_ctrl *ctrl, struct nvme_id_ctrl *id)
+ mutex_lock(&nvme_subsystems_lock);
+ found = __nvme_find_get_subsystem(subsys->subnqn);
+ if (found) {
+- __nvme_release_subsystem(subsys);
++ put_device(&subsys->dev);
+ subsys = found;
+
+ if (!nvme_validate_cntlid(subsys, ctrl, id)) {
+--
+2.22.0
+
diff --git a/series.conf b/series.conf
index bd16a778de..4d1ec03fc4 100644
--- a/series.conf
+++ b/series.conf
@@ -1124,6 +1124,7 @@
patches.kernel.org/5.2.9-101-drbd-dynamically-allocate-shash-descriptor.patch
patches.kernel.org/5.2.9-102-ACPI-IORT-Fix-off-by-one-check-in-iort_dev_find.patch
patches.kernel.org/5.2.9-103-nvme-ignore-subnqn-for-ADATA-SX6000LNP.patch
+ patches.kernel.org/5.2.9-104-nvme-fix-memory-leak-caused-by-incorrect-subsys.patch
########################################################
# Build fixes that apply to the vanilla kernel too.