Prevent list corruption in efivar_entry_remove() and efivar_entry_list_del_unlock() by verifying that an entry is still in the list (list_empty() == false) before calling list_del(). Also reset the list pointers with INIT_LIST_HEAD() to avoid potential double-removal issues. Ensure robust handling of entries and prevent the kernel BUG observed when list_del() was called on an already-removed entry. Fix https://syzkaller.appspot.com/bug?extid=246ea4feed277471958a Syzkaller report: list_del corruption. prev->next should be ffff0000d86d6828, but was ffff800016216e60. (prev=ffff800016216e60) ------------[ cut here ]------------ kernel BUG at lib/list_debug.c:61! Internal error: Oops - BUG: 00000000f2000800 [#1] PREEMPT SMP Modules linked in: CPU: 0 PID: 4299 Comm: syz-executor237 Not tainted 6.1.119-syzkaller #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 09/13/2024 pstate: 60400005 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) pc : __list_del_entry_valid+0x13c/0x158 lib/list_debug.c:59 lr : __list_del_entry_valid+0x13c/0x158 lib/list_debug.c:59 Call trace: __list_del_entry_valid+0x13c/0x158 lib/list_debug.c:59 __list_del_entry include/linux/list.h:134 [inline] list_del include/linux/list.h:148 [inline] efivar_entry_remove+0x38/0x110 fs/efivarfs/vars.c:493 efivarfs_destroy+0x20/0x3c fs/efivarfs/super.c:184 efivar_entry_iter+0x94/0xdc fs/efivarfs/vars.c:720 efivarfs_kill_sb+0x58/0x70 fs/efivarfs/super.c:258 deactivate_locked_super+0xac/0x124 fs/super.c:332 deactivate_super+0xf0/0x110 fs/super.c:363 cleanup_mnt+0x394/0x41c fs/namespace.c:1186 __cleanup_mnt+0x20/0x30 fs/namespace.c:1193 task_work_run+0x240/0x2f0 kernel/task_work.c:203 resume_user_mode_work include/linux/resume_user_mode.h:49 [inline] do_notify_resume+0x2080/0x2cb8 arch/arm64/kernel/signal.c:1132 prepare_exit_to_user_mode arch/arm64/kernel/entry-common.c:137 [inline] exit_to_user_mode arch/arm64/kernel/entry-common.c:142 [inline] el0_svc+0x9c/0x168 arch/arm64/kernel/entry-common.c:638 el0t_64_sync_handler+0x84/0xf0 arch/arm64/kernel/entry-common.c:655 el0t_64_sync+0x18c/0x190 arch/arm64/kernel/entry.S:585 Reported-by: syzbot+75dc11...@xxxxxxxxxxxxxxxxxxxxxxxxx Fixes: 2d82e6227ea1 ("efi: vars: Move efivar caching layer into efivarfs") Cc: stable@xxxxxxxxxxxxxxx Signed-off-by: Alexey Nepomnyashih <sdl@xxxxxxxx> --- fs/efivarfs/vars.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/fs/efivarfs/vars.c b/fs/efivarfs/vars.c index 13bc60698955..42977138e30b 100644 --- a/fs/efivarfs/vars.c +++ b/fs/efivarfs/vars.c @@ -490,7 +490,10 @@ void __efivar_entry_add(struct efivar_entry *entry, struct list_head *head) */ void efivar_entry_remove(struct efivar_entry *entry) { - list_del(&entry->list); + if (!list_empty(&entry->list)) { + list_del(&entry->list); + INIT_LIST_HEAD(&entry->list); + } } /* @@ -506,7 +509,10 @@ void efivar_entry_remove(struct efivar_entry *entry) */ static void efivar_entry_list_del_unlock(struct efivar_entry *entry) { - list_del(&entry->list); + if (!list_empty(&entry->list)) { + list_del(&entry->list); + INIT_LIST_HEAD(&entry->list); + } efivar_unlock(); } -- 2.43.0