Forwarded: [PATCH] netdevsim: fib: replace flush_work() with cancel_work_sync() in nsim_fib_flush_work()
From: syzbot
Date: Wed Mar 18 2026 - 11:02:47 EST
For archival purposes, forwarding an incoming command email to
linux-kernel@xxxxxxxxxxxxxxx, syzkaller-bugs@xxxxxxxxxxxxxxxx.
***
Subject: [PATCH] netdevsim: fib: replace flush_work() with cancel_work_sync() in nsim_fib_flush_work()
Author: kartikey406@xxxxxxxxx
#syz test: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master
nsim_fib_flush_work() calls flush_work() on fib_event_work before
acquiring fib_lock. However, fib_event_work also acquires fib_lock
while processing fib events. If fib_event_work is processing a large
number of events, flush_work() will wait indefinitely causing a hung
task splat.
Fix this by replacing flush_work() with cancel_work_sync() in
nsim_fib_flush_work() to cancel any pending fib_event_work instead
of waiting for it to complete.
Note that flush_work() is intentionally kept in nsim_fib_destroy()
since fib notifiers are already unregistered at that point, meaning
no new fib events can be queued and it is safe to flush the remaining
events.
The following call chain triggers the hang:
nsim_fib_flush_work()
flush_work(&data->fib_event_work) <- waits forever
nsim_fib_event_work()
mutex_lock(&data->fib_lock) <- held while processing
Reported-by: syzbot+7c11975a7e4a2735d529@xxxxxxxxxxxxxxxxxxxxxxxxx
Link: https://syzkaller.appspot.com/bug?extid=7c11975a7e4a2735d529
Signed-off-by: Deepanshu Kartikey <Kartikey406@xxxxxxxxx>
---
drivers/net/netdevsim/fib.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/netdevsim/fib.c b/drivers/net/netdevsim/fib.c
index 1a42bdbfaa41..bca190aa167e 100644
--- a/drivers/net/netdevsim/fib.c
+++ b/drivers/net/netdevsim/fib.c
@@ -1505,7 +1505,7 @@ static void nsim_fib_flush_work(struct work_struct *work)
struct nsim_fib_rt *fib_rt, *fib_rt_tmp;
/* Process pending work. */
- flush_work(&data->fib_event_work);
+ cancel_work_sync(&data->fib_event_work);
mutex_lock(&data->fib_lock);
list_for_each_entry_safe(fib_rt, fib_rt_tmp, &data->fib_rt_list, list) {
--
2.43.0