When CONFIG_MTD_UBI_FASTMAP is enabled, fm_anchor will be assigned a free PEB during ubi_wl_init() or ubi_update_fastmap(). However if fastmap is not used or disabled on the MTD device, ubi_wl_entry related with the PEB will not be freed during detach. So Fix it by freeing the unused fastmap anchor during detach. And also don't generate the initial fm_anchor when fastmap is disabled. Fixes: f9c34bb52997 ("ubi: Fix producing anchor PEBs") Reported-by: syzbot+f317896aae32eb281a58@xxxxxxxxxxxxxxxxxxxxxxxxx Signed-off-by: Hou Tao <houtao1@xxxxxxxxxx> --- drivers/mtd/ubi/fastmap-wl.c | 15 +++++++++++++-- drivers/mtd/ubi/wl.c | 3 ++- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/drivers/mtd/ubi/fastmap-wl.c b/drivers/mtd/ubi/fastmap-wl.c index 426820ab9afe..b486250923c5 100644 --- a/drivers/mtd/ubi/fastmap-wl.c +++ b/drivers/mtd/ubi/fastmap-wl.c @@ -39,6 +39,13 @@ static struct ubi_wl_entry *find_anchor_wl_entry(struct rb_root *root) return victim; } +static inline void return_unused_peb(struct ubi_device *ubi, + struct ubi_wl_entry *e) +{ + wl_tree_add(e, &ubi->free); + ubi->free_count++; +} + /** * return_unused_pool_pebs - returns unused PEB to the free tree. * @ubi: UBI device description object @@ -52,8 +59,7 @@ static void return_unused_pool_pebs(struct ubi_device *ubi, for (i = pool->used; i < pool->size; i++) { e = ubi->lookuptbl[pool->pebs[i]]; - wl_tree_add(e, &ubi->free); - ubi->free_count++; + return_unused_peb(ubi, e); } } @@ -361,6 +367,11 @@ static void ubi_fastmap_close(struct ubi_device *ubi) return_unused_pool_pebs(ubi, &ubi->fm_pool); return_unused_pool_pebs(ubi, &ubi->fm_wl_pool); + if (ubi->fm_anchor) { + return_unused_peb(ubi, ubi->fm_anchor); + ubi->fm_anchor = NULL; + } + if (ubi->fm) { for (i = 0; i < ubi->fm->used_blocks; i++) kfree(ubi->fm->e[i]); diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index 5d77a38dba54..c6c2b8dc96c7 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c @@ -1876,7 +1876,8 @@ int ubi_wl_init(struct ubi_device *ubi, struct ubi_attach_info *ai) goto out_free; #ifdef CONFIG_MTD_UBI_FASTMAP - ubi_ensure_anchor_pebs(ubi); + if (!ubi->fm_disabled) + ubi_ensure_anchor_pebs(ubi); #endif return 0; -- 2.22.0 ______________________________________________________ Linux MTD discussion mailing list http://lists.infradead.org/mailman/listinfo/linux-mtd/