Skip to content

Commit d133e30

Browse files
btzdsrichardweinberger
authored andcommitted
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 <[email protected]> Reviewed-by: Zhihao Cheng <[email protected]> Signed-off-by: Richard Weinberger <[email protected]>
1 parent 77530d1 commit d133e30

File tree

3 files changed

+16
-8
lines changed

3 files changed

+16
-8
lines changed

drivers/mtd/ubi/attach.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1600,7 +1600,7 @@ int ubi_attach(struct ubi_device *ubi, int force_scan)
16001600

16011601
err = ubi_read_volume_table(ubi, ai);
16021602
if (err)
1603-
goto out_ai;
1603+
goto out_fm;
16041604

16051605
err = ubi_wl_init(ubi, ai);
16061606
if (err)
@@ -1642,6 +1642,8 @@ int ubi_attach(struct ubi_device *ubi, int force_scan)
16421642
out_vtbl:
16431643
ubi_free_all_volumes(ubi);
16441644
vfree(ubi->vtbl);
1645+
out_fm:
1646+
ubi_free_fastmap(ubi);
16451647
out_ai:
16461648
destroy_ai(ai);
16471649
return err;

drivers/mtd/ubi/fastmap-wl.c

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -530,8 +530,6 @@ int ubi_is_erase_work(struct ubi_work *wrk)
530530

531531
static void ubi_fastmap_close(struct ubi_device *ubi)
532532
{
533-
int i;
534-
535533
return_unused_pool_pebs(ubi, &ubi->fm_pool);
536534
return_unused_pool_pebs(ubi, &ubi->fm_wl_pool);
537535

@@ -540,11 +538,7 @@ static void ubi_fastmap_close(struct ubi_device *ubi)
540538
ubi->fm_anchor = NULL;
541539
}
542540

543-
if (ubi->fm) {
544-
for (i = 0; i < ubi->fm->used_blocks; i++)
545-
kfree(ubi->fm->e[i]);
546-
}
547-
kfree(ubi->fm);
541+
ubi_free_fastmap(ubi);
548542
}
549543

550544
/**

drivers/mtd/ubi/ubi.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -969,10 +969,22 @@ int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai,
969969
struct ubi_attach_info *scan_ai);
970970
int ubi_fastmap_init_checkmap(struct ubi_volume *vol, int leb_count);
971971
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+
}
972983
#else
973984
static inline int ubi_update_fastmap(struct ubi_device *ubi) { return 0; }
974985
static inline int ubi_fastmap_init_checkmap(struct ubi_volume *vol, int leb_count) { return 0; }
975986
static inline void ubi_fastmap_destroy_checkmap(struct ubi_volume *vol) {}
987+
static inline void ubi_free_fastmap(struct ubi_device *ubi) { }
976988
#endif
977989

978990
/* block.c */

0 commit comments

Comments
 (0)