Patch "nvdimm: Fix devs leaks in scan_labels()" has been added to the 6.6-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    nvdimm: Fix devs leaks in scan_labels()

to the 6.6-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     nvdimm-fix-devs-leaks-in-scan_labels.patch
and it can be found in the queue-6.6 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit cb4409a507250e4c9e71b1bf82eae0d0ed4cfc24
Author: Li Zhijian <lizhijian@xxxxxxxxxxx>
Date:   Mon Aug 19 14:20:44 2024 +0800

    nvdimm: Fix devs leaks in scan_labels()
    
    [ Upstream commit 62c2aa6b1f565d2fc1ec11a6e9e8336ce37a6426 ]
    
    scan_labels() leaks memory when label scanning fails and it falls back
    to just creating a default "seed" namespace for userspace to configure.
    Root can force the kernel to leak memory.
    
    Allocate the minimum resources unconditionally and release them when
    unneeded to avoid the memory leak.
    
    A kmemleak reports:
    unreferenced object 0xffff88800dda1980 (size 16):
      comm "kworker/u10:5", pid 69, jiffies 4294671781
      hex dump (first 16 bytes):
        00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
      backtrace (crc 0):
        [<00000000c5dea560>] __kmalloc+0x32c/0x470
        [<000000009ed43c83>] nd_region_register_namespaces+0x6fb/0x1120 [libnvdimm]
        [<000000000e07a65c>] nd_region_probe+0xfe/0x210 [libnvdimm]
        [<000000007b79ce5f>] nvdimm_bus_probe+0x7a/0x1e0 [libnvdimm]
        [<00000000a5f3da2e>] really_probe+0xc6/0x390
        [<00000000129e2a69>] __driver_probe_device+0x78/0x150
        [<000000002dfed28b>] driver_probe_device+0x1e/0x90
        [<00000000e7048de2>] __device_attach_driver+0x85/0x110
        [<0000000032dca295>] bus_for_each_drv+0x85/0xe0
        [<00000000391c5a7d>] __device_attach+0xbe/0x1e0
        [<0000000026dabec0>] bus_probe_device+0x94/0xb0
        [<00000000c590d936>] device_add+0x656/0x870
        [<000000003d69bfaa>] nd_async_device_register+0xe/0x50 [libnvdimm]
        [<000000003f4c52a4>] async_run_entry_fn+0x2e/0x110
        [<00000000e201f4b0>] process_one_work+0x1ee/0x600
        [<000000006d90d5a9>] worker_thread+0x183/0x350
    
    Cc: Dave Jiang <dave.jiang@xxxxxxxxx>
    Cc: Ira Weiny <ira.weiny@xxxxxxxxx>
    Fixes: 1b40e09a1232 ("libnvdimm: blk labels and namespace instantiation")
    Suggested-by: Dan Williams <dan.j.williams@xxxxxxxxx>
    Signed-off-by: Li Zhijian <lizhijian@xxxxxxxxxxx>
    Reviewed-by: Dan Williams <dan.j.williams@xxxxxxxxx>
    Reviewed-by: Ira Weiny <ira.weiny@xxxxxxxxx>
    Link: https://patch.msgid.link/20240819062045.1481298-1-lizhijian@xxxxxxxxxxx
    Signed-off-by: Ira Weiny <ira.weiny@xxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/drivers/nvdimm/namespace_devs.c b/drivers/nvdimm/namespace_devs.c
index 07177eadc56e8..1ea8c27e8874d 100644
--- a/drivers/nvdimm/namespace_devs.c
+++ b/drivers/nvdimm/namespace_devs.c
@@ -1927,12 +1927,16 @@ static int cmp_dpa(const void *a, const void *b)
 static struct device **scan_labels(struct nd_region *nd_region)
 {
 	int i, count = 0;
-	struct device *dev, **devs = NULL;
+	struct device *dev, **devs;
 	struct nd_label_ent *label_ent, *e;
 	struct nd_mapping *nd_mapping = &nd_region->mapping[0];
 	struct nvdimm_drvdata *ndd = to_ndd(nd_mapping);
 	resource_size_t map_end = nd_mapping->start + nd_mapping->size - 1;
 
+	devs = kcalloc(2, sizeof(dev), GFP_KERNEL);
+	if (!devs)
+		return NULL;
+
 	/* "safe" because create_namespace_pmem() might list_move() label_ent */
 	list_for_each_entry_safe(label_ent, e, &nd_mapping->labels, list) {
 		struct nd_namespace_label *nd_label = label_ent->label;
@@ -1951,12 +1955,14 @@ static struct device **scan_labels(struct nd_region *nd_region)
 			goto err;
 		if (i < count)
 			continue;
-		__devs = kcalloc(count + 2, sizeof(dev), GFP_KERNEL);
-		if (!__devs)
-			goto err;
-		memcpy(__devs, devs, sizeof(dev) * count);
-		kfree(devs);
-		devs = __devs;
+		if (count) {
+			__devs = kcalloc(count + 2, sizeof(dev), GFP_KERNEL);
+			if (!__devs)
+				goto err;
+			memcpy(__devs, devs, sizeof(dev) * count);
+			kfree(devs);
+			devs = __devs;
+		}
 
 		dev = create_namespace_pmem(nd_region, nd_mapping, nd_label);
 		if (IS_ERR(dev)) {
@@ -1983,11 +1989,6 @@ static struct device **scan_labels(struct nd_region *nd_region)
 
 		/* Publish a zero-sized namespace for userspace to configure. */
 		nd_mapping_free_labels(nd_mapping);
-
-		devs = kcalloc(2, sizeof(dev), GFP_KERNEL);
-		if (!devs)
-			goto err;
-
 		nspm = kzalloc(sizeof(*nspm), GFP_KERNEL);
 		if (!nspm)
 			goto err;
@@ -2026,11 +2027,10 @@ static struct device **scan_labels(struct nd_region *nd_region)
 	return devs;
 
  err:
-	if (devs) {
-		for (i = 0; devs[i]; i++)
-			namespace_pmem_release(devs[i]);
-		kfree(devs);
-	}
+	for (i = 0; devs[i]; i++)
+		namespace_pmem_release(devs[i]);
+	kfree(devs);
+
 	return NULL;
 }
 




[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux