linux/drivers/mtd/ubi
Zhihao Cheng cc4bc532ac ubi: ubi_wl_put_peb: Fix infinite loop when wear-leveling work failed
[ Upstream commit 4d57a7333e ]

Following process will trigger an infinite loop in ubi_wl_put_peb():

	ubifs_bgt		ubi_bgt
ubifs_leb_unmap
  ubi_leb_unmap
    ubi_eba_unmap_leb
      ubi_wl_put_peb	wear_leveling_worker
                          e1 = rb_entry(rb_first(&ubi->used)
			  e2 = get_peb_for_wl(ubi)
			  ubi_io_read_vid_hdr  // return err (flash fault)
			  out_error:
			    ubi->move_from = ubi->move_to = NULL
			    wl_entry_destroy(ubi, e1)
			      ubi->lookuptbl[e->pnum] = NULL
      retry:
        e = ubi->lookuptbl[pnum];	// return NULL
	if (e == ubi->move_from) {	// NULL == NULL gets true
	  goto retry;			// infinite loop !!!

$ top
  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     COMMAND
  7676 root     20   0       0      0      0 R 100.0  0.0  ubifs_bgt0_0

Fix it by:
 1) Letting ubi_wl_put_peb() returns directly if wearl leveling entry has
    been removed from 'ubi->lookuptbl'.
 2) Using 'ubi->wl_lock' protecting wl entry deletion to preventing an
    use-after-free problem for wl entry in ubi_wl_put_peb().

Fetch a reproducer in [Link].

Fixes: 43f9b25a9c ("UBI: bugfix: protect from volume removal")
Fixes: ee59ba8b06 ("UBI: Fix stale pointers in ubi->lookuptbl")
Link: https://bugzilla.kernel.org/show_bug.cgi?id=216111
Signed-off-by: Zhihao Cheng <chengzhihao1@huawei.com>
Signed-off-by: Richard Weinberger <richard@nod.at>
Signed-off-by: Sasha Levin <sashal@kernel.org>
History 2023-03-11 13:55:21 +01:00
..
attach.c mtd: Convert fallthrough comments into statements 2020-03-30 10:14:54 +02:00
block.c ubi: block: Fix typos in comments 2022-09-21 11:32:27 +02:00
build.c ubi: Fix possible null-ptr-deref in ubi_free_volume() 2023-03-11 13:55:20 +01:00
cdev.c ubi: fastmap: Add fastmap control support for 'UBI_IOCATT' ioctl 2022-09-21 18:29:18 +02:00
debug.c treewide: use prandom_u32_max() when possible, part 1 2022-10-11 17:42:55 -06:00
debug.h treewide: use prandom_u32_max() when possible, part 1 2022-10-11 17:42:55 -06:00
eba.c ubi: Fix repeated words in comments 2022-09-21 11:32:27 +02:00
fastmap-wl.c ubi: fastmap: Fix missed fm_anchor PEB in wear-leveling after disabling fastmap 2023-03-11 13:55:21 +01:00
fastmap.c ubi: fastmap: Use the bitmap API to allocate bitmaps 2022-09-21 11:32:58 +02:00
gluebi.c mtd: ubi: gluebi: Fix misnamed function parameter documentation 2020-11-20 12:37:32 +01:00
io.c ubi: Fix repeated words in comments 2022-09-21 11:32:27 +02:00
kapi.c mtd: ubi: kapi: Correct documentation for 'ubi_leb_read_sg's 'sgl' parameter 2020-11-20 12:37:31 +01:00
Kconfig treewide: Add SPDX license identifier - Makefile/Kconfig 2019-05-21 10:50:46 +02:00
Makefile License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
misc.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 156 2019-05-30 11:26:35 -07:00
ubi-media.h ubi: ubi-media.h: Fix comment typo 2022-09-21 11:12:18 +02:00
ubi.h ubi: fastmap: Add fastmap control support for 'UBI_IOCATT' ioctl 2022-09-21 18:29:18 +02:00
upd.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 156 2019-05-30 11:26:35 -07:00
vmt.c ubi: Fix possible null-ptr-deref in ubi_free_volume() 2023-03-11 13:55:20 +01:00
vtbl.c ubi: Free the normal volumes in error paths of ubi_attach_mtd_dev() 2020-01-16 23:35:59 +01:00
wl.c ubi: ubi_wl_put_peb: Fix infinite loop when wear-leveling work failed 2023-03-11 13:55:21 +01:00
wl.h ubi: fastmap: Check wl_pool for free peb before wear leveling 2022-05-27 16:49:07 +02:00