Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

ubi: fastmap: fix ubi->fm memory leak

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
=================================================================
BUG ubi_wl_entry_slab (Tainted: G B O L ): Objects remaining in ubi_wl_entry_slab on __kmem_cache_shutdown()
-----------------------------------------------------------------------------

Slab 0xffff2fd23a40cd00 objects=22 used=1 fp=0xffff2fd1d0334fd8 flags=0x883fffc010200(slab|head|section=34|node=0|zone=1|lastcpupid=0x7fff)
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=3688
Allocated in ubi_scan_fastmap+0xf04/0xf40 [ubi] age=80 cpu=0 pid=5884
__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=220744

Signed-off-by: Liyuan Pang <pangliyuan1@huawei.com>
Reviewed-by: Zhihao Cheng <chengzhihao1@huawei.com>
Signed-off-by: Richard Weinberger <richard@nod.at>

authored by

Liyuan Pang and committed by
Richard Weinberger
d133e30a 77530d1a

+16 -8
+3 -1
drivers/mtd/ubi/attach.c
··· 1600 1600 1601 1601 err = ubi_read_volume_table(ubi, ai); 1602 1602 if (err) 1603 - goto out_ai; 1603 + goto out_fm; 1604 1604 1605 1605 err = ubi_wl_init(ubi, ai); 1606 1606 if (err) ··· 1642 1642 out_vtbl: 1643 1643 ubi_free_all_volumes(ubi); 1644 1644 vfree(ubi->vtbl); 1645 + out_fm: 1646 + ubi_free_fastmap(ubi); 1645 1647 out_ai: 1646 1648 destroy_ai(ai); 1647 1649 return err;
+1 -7
drivers/mtd/ubi/fastmap-wl.c
··· 530 530 531 531 static void ubi_fastmap_close(struct ubi_device *ubi) 532 532 { 533 - int i; 534 - 535 533 return_unused_pool_pebs(ubi, &ubi->fm_pool); 536 534 return_unused_pool_pebs(ubi, &ubi->fm_wl_pool); 537 535 ··· 538 540 ubi->fm_anchor = NULL; 539 541 } 540 542 541 - if (ubi->fm) { 542 - for (i = 0; i < ubi->fm->used_blocks; i++) 543 - kfree(ubi->fm->e[i]); 544 - } 545 - kfree(ubi->fm); 543 + ubi_free_fastmap(ubi); 546 544 } 547 545 548 546 /**
+12
drivers/mtd/ubi/ubi.h
··· 969 969 struct ubi_attach_info *scan_ai); 970 970 int ubi_fastmap_init_checkmap(struct ubi_volume *vol, int leb_count); 971 971 void ubi_fastmap_destroy_checkmap(struct ubi_volume *vol); 972 + static inline void ubi_free_fastmap(struct ubi_device *ubi) 973 + { 974 + if (ubi->fm) { 975 + int i; 976 + 977 + for (i = 0; i < ubi->fm->used_blocks; i++) 978 + kmem_cache_free(ubi_wl_entry_slab, ubi->fm->e[i]); 979 + kfree(ubi->fm); 980 + ubi->fm = NULL; 981 + } 982 + } 972 983 #else 973 984 static inline int ubi_update_fastmap(struct ubi_device *ubi) { return 0; } 974 985 static inline int ubi_fastmap_init_checkmap(struct ubi_volume *vol, int leb_count) { return 0; } 975 986 static inline void ubi_fastmap_destroy_checkmap(struct ubi_volume *vol) {} 987 + static inline void ubi_free_fastmap(struct ubi_device *ubi) { } 976 988 #endif 977 989 978 990 /* block.c */