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: Revert "ubi: wl: Close down wear-leveling before nand is suspended"

Commit 5580cdae05ae ("ubi: wl: Close down wear-leveling before nand is
suspended") added a reboot notification in UBI layer to shutdown the
wear-leveling subsystem, which imported an UAF problem[1]. Besides that,
the method also brings other potential UAF problems, for example:
reboot kworker
ubi_wl_reboot_notifier
ubi_wl_close
ubi_fastmap_close
kfree(ubi->fm)
update_fastmap_work_fn
ubi_update_fastmap
old_fm = ubi->fm
if (old_fm && old_fm->e[i]) // UAF!

Actually, the problem fixed by commit 5580cdae05ae ("ubi: wl: Close down
wear-leveling before nand is suspended") has been solved by commit
8cba323437a4 ("mtd: rawnand: protect access to rawnand devices while in
suspend"), which was discussed in [2]. So we can revert the commit
5580cdae05ae ("ubi: wl: Close down wear-leveling before nand is
suspended") directly.

[1] https://lore.kernel.org/linux-mtd/20241208175211.9406-2-dennis.lamerice@gmail.com/
[2] https://lore.kernel.org/all/9bf76f5d-12a4-46ff-90d4-4a7f0f47c381@axis.com/

Fixes: 5580cdae05ae ("ubi: wl: Close down wear-leveling before nand is suspended")
Reported-by: Dennis Lam <dennis.lamerice@gmail.com>
Closes: https://lore.kernel.org/linux-mtd/20241208175211.9406-2-dennis.lamerice@gmail.com/
Signed-off-by: Zhihao Cheng <chengzhihao1@huawei.com>
Acked-by: Mårten Lindahl <marten.lindahl@axis.com>
Signed-off-by: Richard Weinberger <richard@nod.at>

authored by

Zhihao Cheng and committed by
Richard Weinberger
844c6fdc 404de7ab

-23
-2
drivers/mtd/ubi/ubi.h
··· 549 549 * @peb_buf: a buffer of PEB size used for different purposes 550 550 * @buf_mutex: protects @peb_buf 551 551 * @ckvol_mutex: serializes static volume checking when opening 552 - * @wl_reboot_notifier: close all wear-leveling work before reboot 553 552 * 554 553 * @dbg: debugging information for this UBI device 555 554 */ ··· 651 652 void *peb_buf; 652 653 struct mutex buf_mutex; 653 654 struct mutex ckvol_mutex; 654 - struct notifier_block wl_reboot_notifier; 655 655 656 656 struct ubi_debug_info dbg; 657 657 };
-21
drivers/mtd/ubi/wl.c
··· 89 89 #include <linux/crc32.h> 90 90 #include <linux/freezer.h> 91 91 #include <linux/kthread.h> 92 - #include <linux/reboot.h> 93 92 #include "ubi.h" 94 93 #include "wl.h" 95 94 ··· 127 128 struct ubi_wl_entry *e, struct rb_root *root); 128 129 static int self_check_in_pq(const struct ubi_device *ubi, 129 130 struct ubi_wl_entry *e); 130 - static int ubi_wl_reboot_notifier(struct notifier_block *n, 131 - unsigned long state, void *cmd); 132 131 133 132 /** 134 133 * wl_tree_add - add a wear-leveling entry to a WL RB-tree. ··· 1950 1953 if (!ubi->ro_mode && !ubi->fm_disabled) 1951 1954 ubi_ensure_anchor_pebs(ubi); 1952 1955 #endif 1953 - 1954 - if (!ubi->wl_reboot_notifier.notifier_call) { 1955 - ubi->wl_reboot_notifier.notifier_call = ubi_wl_reboot_notifier; 1956 - ubi->wl_reboot_notifier.priority = 1; /* Higher than MTD */ 1957 - register_reboot_notifier(&ubi->wl_reboot_notifier); 1958 - } 1959 - 1960 1956 return 0; 1961 1957 1962 1958 out_free: ··· 1993 2003 tree_destroy(ubi, &ubi->free); 1994 2004 tree_destroy(ubi, &ubi->scrub); 1995 2005 kfree(ubi->lookuptbl); 1996 - } 1997 - 1998 - static int ubi_wl_reboot_notifier(struct notifier_block *n, 1999 - unsigned long state, void *cmd) 2000 - { 2001 - struct ubi_device *ubi; 2002 - 2003 - ubi = container_of(n, struct ubi_device, wl_reboot_notifier); 2004 - ubi_wl_close(ubi); 2005 - 2006 - return NOTIFY_DONE; 2007 2006 } 2008 2007 2009 2008 /**