From nobody Fri Dec 19 12:52:22 2025 Received: from canpmsgout04.his.huawei.com (canpmsgout04.his.huawei.com [113.46.200.219]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 63518747F for ; Fri, 7 Nov 2025 10:01:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=113.46.200.219 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762509670; cv=none; b=QWfWK0lWzYapk5dw0MuLeyJIpRdzwcy+YYSnry8BzdRP659W1V/AvbH4CuxVFzxRerIMvIu9L0bOCvdqE25+QIqOKAPWPcQmuK8pdry1L/N2x7oPvdW+oGSnqxVl+TNFZKqP5cfYl/trwZPmJ+nTZPflxbBFs6eRTZvx5qyrrm4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762509670; c=relaxed/simple; bh=HepG1Ng1Ue+PZAfCqDvp/p2r9nrcrYxZdxz+BaGJxT8=; h=From:To:CC:Subject:Date:Message-ID:MIME-Version:Content-Type; b=FM503Aafg8hOt9EGcQfG48G+sn6RS7E9mdz7Va8AznbvvObk6Ec0JfDYhiGrIv9pGRCueXljTeM8WZtYkvEAN/eBF2W31tqjpSWMq4p4rY6uorzzxlvwHK6eSND2HMNIG311XzncyoLAVFxS7F7jv6ehJPGJGHa6HPfc9VFYl7Q= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com; spf=pass smtp.mailfrom=huawei.com; dkim=pass (1024-bit key) header.d=huawei.com header.i=@huawei.com header.b=NzQFRO5G; arc=none smtp.client-ip=113.46.200.219 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huawei.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=huawei.com header.i=@huawei.com header.b="NzQFRO5G" dkim-signature: v=1; a=rsa-sha256; d=huawei.com; s=dkim; c=relaxed/relaxed; q=dns/txt; h=From; bh=7kX1Xy2V1MN3IMg82+bocMlGGOsUiexNBkEAtBouJgU=; b=NzQFRO5Gm300s7UctdcQgLIGYzyHgX6kdO8MUmXHveqhUE/YrMrn0ZyOV/E4bg2iWkPI2EHD/ ltJWoV/VSBpfpe6X4Y165XAbaJ1wMvnUBuDMgR6pE1iZS92N+siBr0sgk9keQvnL33vQCw3mZK8 4CphrojZy9QXAtvf+u6uYII= Received: from mail.maildlp.com (unknown [172.19.163.174]) by canpmsgout04.his.huawei.com (SkyGuard) with ESMTPS id 4d2vfk0xVGz1prlB; Fri, 7 Nov 2025 17:59:26 +0800 (CST) Received: from dggemv705-chm.china.huawei.com (unknown [10.3.19.32]) by mail.maildlp.com (Postfix) with ESMTPS id 344CB1402FC; Fri, 7 Nov 2025 18:01:03 +0800 (CST) Received: from kwepemq100008.china.huawei.com (7.202.195.91) by dggemv705-chm.china.huawei.com (10.3.19.32) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.11; Fri, 7 Nov 2025 18:01:03 +0800 Received: from DESKTOP-DKE2JV6.huawei.com (10.67.110.146) by kwepemq100008.china.huawei.com (7.202.195.91) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.11; Fri, 7 Nov 2025 18:01:02 +0800 From: Liyuan Pang To: , , , , , , CC: , , , , , , Liyuan Pang Subject: [PATCH v2] ubi: fastmap: fix ubi->fm memory leak Date: Fri, 7 Nov 2025 18:00:57 +0800 Message-ID: <20251107100057.1091153-1-pangliyuan1@huawei.com> X-Mailer: git-send-email 2.34.1 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: kwepems500001.china.huawei.com (7.221.188.70) To kwepemq100008.china.huawei.com (7.202.195.91) Content-Type: text/plain; charset="utf-8" The problem is that scan_fast() allocate memory for ubi->fm and ubi->fm->e[x], but if the following attach process fails in ubi_wl_init or ubi_read_volume_table, the whole attach process will fail without executing ubi_wl_close to free the memory under ubi->fm. Fix this by add a new ubi_free_fastmap function in fastmap.c to free the memory allocated for fm. If SLUB_DEBUG and KUNIT are enabled, the following warning messages will show: ubi0: detaching mtd0 ubi0: mtd0 is detached ubi0: default fastmap pool size: 200 ubi0: default fastmap WL pool size: 100 ubi0: attaching mtd0 ubi0: attached by fastmap ubi0: fastmap pool size: 200 ubi0: fastmap WL pool size: 100 ubi0 error: ubi_wl_init [ubi]: no enough physical eraseblocks (4, need 203) ubi0 error: ubi_attach_mtd_dev [ubi]: failed to attach mtd0, error -28 UBI error: cannot attach mtd0 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D BUG ubi_wl_entry_slab (Tainted: G B O L ): Objects remaining in u= bi_wl_entry_slab on __kmem_cache_shutdown() Reviewed-by: Zhihao Cheng ---------------------------------------------------------------------------= -- Slab 0xffff2fd23a40cd00 objects=3D22 used=3D1 fp=3D0xffff2fd1d0334fd8 flags= =3D0x883fffc010200(slab|head|section=3D34|node=3D0|zone=3D1|lastcpupid=3D0x= 7fff) CPU: 0 PID: 5884 Comm: insmod Tainted: G B O L 5.10.0 #1 Hardware name: LS1043A RDB Board (DT) Call trace: dump_backtrace+0x0/0x198 show_stack+0x18/0x28 dump_stack+0xe8/0x15c slab_err+0x94/0xc0 __kmem_cache_shutdown+0x1fc/0x39c kmem_cache_destroy+0x48/0x138 ubi_init+0x1d4/0xf34 [ubi] do_one_initcall+0xb4/0x24c do_init_module+0x4c/0x1dc load_module+0x212c/0x2260 __se_sys_finit_module+0xb4/0xd8 __arm64_sys_finit_module+0x18/0x28 el0_svc_common.constprop.0+0x78/0x1a0 do_el0_svc+0x78/0x90 el0_svc+0x20/0x38 el0_sync_handler+0xf0/0x140 normal+0x3d8/0x400 Object 0xffff2fd1d0334e68 @offset=3D3688 Allocated in ubi_scan_fastmap+0xf04/0xf40 [ubi] age=3D80 cpu=3D0 pid=3D5884 __slab_alloc.isra.21+0x6c/0xb4 kmem_cache_alloc+0x1e4/0x80c ubi_scan_fastmap+0xf04/0xf40 [ubi] ubi_attach+0x1f0/0x3a8 [ubi] ubi_attach_mtd_dev+0x810/0xbc8 [ubi] ubi_init+0x238/0xf34 [ubi] do_one_initcall+0xb4/0x24c do_init_module+0x4c/0x1dc load_module+0x212c/0x2260 __se_sys_finit_module+0xb4/0xd8 __arm64_sys_finit_module+0x18/0x28 el0_svc_common.constprop.0+0x78/0x1a0 do_el0_svc+0x78/0x90 el0_svc+0x20/0x38 el0_sync_handler+0xf0/0x140 normal+0x3d8/0x400 Link: https://bugzilla.kernel.org/show_bug.cgi?id=3D220744 Signed-off-by: Liyuan Pang Reviewed-by: Zhihao Cheng --- Changes in v2: * reduce the scope of variable "i" to the code block of the if branch * make ubi_free_fastmap an static inline function * link to v1: https://lore.kernel.org/linux-mtd/20251107093843.1077536-1-pangliyuan1@hu= awei.com/T/#t --- drivers/mtd/ubi/attach.c | 4 +++- drivers/mtd/ubi/fastmap-wl.c | 8 +------- drivers/mtd/ubi/ubi.h | 12 ++++++++++++ 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/drivers/mtd/ubi/attach.c b/drivers/mtd/ubi/attach.c index adc47b87b38a..884171871d0e 100644 --- a/drivers/mtd/ubi/attach.c +++ b/drivers/mtd/ubi/attach.c @@ -1600,7 +1600,7 @@ int ubi_attach(struct ubi_device *ubi, int force_scan) =20 err =3D ubi_read_volume_table(ubi, ai); if (err) - goto out_ai; + goto out_fm; =20 err =3D ubi_wl_init(ubi, ai); if (err) @@ -1642,6 +1642,8 @@ int ubi_attach(struct ubi_device *ubi, int force_scan) out_vtbl: ubi_free_all_volumes(ubi); vfree(ubi->vtbl); +out_fm: + ubi_free_fastmap(ubi); out_ai: destroy_ai(ai); return err; diff --git a/drivers/mtd/ubi/fastmap-wl.c b/drivers/mtd/ubi/fastmap-wl.c index 9bdb6525f128..e2bc1122bfd3 100644 --- a/drivers/mtd/ubi/fastmap-wl.c +++ b/drivers/mtd/ubi/fastmap-wl.c @@ -530,8 +530,6 @@ int ubi_is_erase_work(struct ubi_work *wrk) =20 static void ubi_fastmap_close(struct ubi_device *ubi) { - int i; - return_unused_pool_pebs(ubi, &ubi->fm_pool); return_unused_pool_pebs(ubi, &ubi->fm_wl_pool); =20 @@ -540,11 +538,7 @@ static void ubi_fastmap_close(struct ubi_device *ubi) ubi->fm_anchor =3D NULL; } =20 - if (ubi->fm) { - for (i =3D 0; i < ubi->fm->used_blocks; i++) - kfree(ubi->fm->e[i]); - } - kfree(ubi->fm); + ubi_free_fastmap(ubi); } =20 /** diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h index c792b9bcab9b..44803d3329f4 100644 --- a/drivers/mtd/ubi/ubi.h +++ b/drivers/mtd/ubi/ubi.h @@ -969,10 +969,22 @@ int ubi_scan_fastmap(struct ubi_device *ubi, struct u= bi_attach_info *ai, struct ubi_attach_info *scan_ai); int ubi_fastmap_init_checkmap(struct ubi_volume *vol, int leb_count); void ubi_fastmap_destroy_checkmap(struct ubi_volume *vol); +static inline void ubi_free_fastmap(struct ubi_device *ubi) +{ + if (ubi->fm) { + int i; + + for (i =3D 0; i < ubi->fm->used_blocks; i++) + kmem_cache_free(ubi_wl_entry_slab, ubi->fm->e[i]); + kfree(ubi->fm); + ubi->fm =3D NULL; + } +} #else static inline int ubi_update_fastmap(struct ubi_device *ubi) { return 0; } static inline int ubi_fastmap_init_checkmap(struct ubi_volume *vol, int le= b_count) { return 0; } static inline void ubi_fastmap_destroy_checkmap(struct ubi_volume *vol) {} +static inline void ubi_free_fastmap(struct ubi_device *ubi) { } #endif =20 /* block.c */ --=20 2.34.1