lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <20250516051318.509064-1-lizhijian@fujitsu.com>
Date: Fri, 16 May 2025 13:13:17 +0800
From: Li Zhijian <lizhijian@...itsu.com>
To: nvdimm@...ts.linux.dev
Cc: dan.j.williams@...el.com,
	vishal.l.verma@...el.com,
	dave.jiang@...el.com,
	ira.weiny@...el.com,
	linux-kernel@...r.kernel.org,
	Li Zhijian <lizhijian@...itsu.com>
Subject: [PATCH 1/2] nvdimm/btt: Fix memleaks in discover_arenas()

kmemleak reported a memleak after the ndctl_test
unreferenced object 0xffff88800e6cf2c0 (size 32):
  comm "modprobe", pid 969, jiffies 4294698691
  hex dump (first 32 bytes):
    03 00 00 00 a0 0a 00 00 00 b0 b4 00 00 c9 ff ff  ................
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  backtrace (crc 807f3e24):
    __kmalloc_cache_noprof+0x331/0x410
    nvdimm_namespace_attach_btt+0xa9b/0xcc0 [nd_btt]
    platform_probe+0x45/0xa0
    ...
    load_module+0x21f9/0x22f0

faddr2line tells that (based on v6.15-rc4):
$ ./scripts/faddr2line drivers/nvdimm/nd_btt.o nvdimm_namespace_attach_btt+0xa9
nvdimm_namespace_attach_btt+0xa9b/0xcc0:
log_set_indices at linux/drivers/nvdimm/btt.c:719
(inlined by) discover_arenas at linux/drivers/nvdimm/btt.c:888
(inlined by) btt_init at linux/drivers/nvdimm/btt.c:1583
(inlined by) nvdimm_namespace_attach_btt at linux/drivers/nvdimm/btt.c:1680

It's believed that this was a false positive because the leaking size
didn't match any instance in an arena.

However during looking into this issue, it's noticed that it does not
release an initializing arena instance and instances in btt->arena_list
in some error paths.

Signed-off-by: Li Zhijian <lizhijian@...itsu.com>
---
 drivers/nvdimm/btt.c | 26 +++++++++++++++++---------
 1 file changed, 17 insertions(+), 9 deletions(-)

diff --git a/drivers/nvdimm/btt.c b/drivers/nvdimm/btt.c
index 423dcd190906..a11e4e7e9a52 100644
--- a/drivers/nvdimm/btt.c
+++ b/drivers/nvdimm/btt.c
@@ -801,17 +801,22 @@ static struct arena_info *alloc_arena(struct btt *btt, size_t size,
 	return arena;
 }
 
+static void free_arena(struct arena_info *arena)
+{
+	kfree(arena->rtt);
+	kfree(arena->map_locks);
+	kfree(arena->freelist);
+	debugfs_remove_recursive(arena->debugfs_dir);
+	kfree(arena);
+}
+
 static void free_arenas(struct btt *btt)
 {
 	struct arena_info *arena, *next;
 
 	list_for_each_entry_safe(arena, next, &btt->arena_list, list) {
 		list_del(&arena->list);
-		kfree(arena->rtt);
-		kfree(arena->map_locks);
-		kfree(arena->freelist);
-		debugfs_remove_recursive(arena->debugfs_dir);
-		kfree(arena);
+		free_arena(arena);
 	}
 }
 
@@ -848,7 +853,7 @@ static void parse_arena_meta(struct arena_info *arena, struct btt_sb *super,
 static int discover_arenas(struct btt *btt)
 {
 	int ret = 0;
-	struct arena_info *arena;
+	struct arena_info *arena = NULL;
 	size_t remaining = btt->rawsize;
 	u64 cur_nlba = 0;
 	size_t cur_off = 0;
@@ -861,8 +866,10 @@ static int discover_arenas(struct btt *btt)
 	while (remaining) {
 		/* Alloc memory for arena */
 		arena = alloc_arena(btt, 0, 0, 0);
-		if (!arena)
-			return -ENOMEM;
+		if (!arena) {
+			ret = -ENOMEM;
+			goto out;
+		}
 
 		arena->infooff = cur_off;
 		ret = btt_info_read(arena, super);
@@ -921,7 +928,8 @@ static int discover_arenas(struct btt *btt)
 	return ret;
 
  out:
-	kfree(arena);
+	if (arena)
+		free_arena(arena);
 	free_arenas(btt);
 	return ret;
 }
-- 
2.47.0


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ