When a filesystem is frozen via the FIFREEZE ioctl, the superblock's write lock is acquired and held until the filesystem is explicitly thawed via FITHAW. Any task attempting to write to the frozen filesystem (e.g., calling open(O_TMPFILE) or unlink) will block in sb_start_write(), waiting for the superblock's read lock. Currently, percpu_rwsem_wait() puts these waiting tasks into the TASK_UNINTERRUPTIBLE state. Since thawing a filesystem relies on an explicit user-space action, the wait can take an arbitrary amount of time. If this wait exceeds the hung task timeout, the watchdog fires and can panic the kernel: INFO: task crond:5389 blocked for more than 15 seconds. task:crond state:D stack:23720 pid:5389 tgid:5389 ppid:1 task_flags:0x400000 flags:0x00080000 Call Trace: __schedule+0x16dc/0x5500 kernel/sched/core.c:7234 schedule+0x164/0x2b0 kernel/sched/core.c:7326 percpu_rwsem_wait+0x32d/0x4a0 kernel/locking/percpu-rwsem.c:164 __percpu_down_read+0xf8/0x140 kernel/locking/percpu-rwsem.c:180 percpu_down_read_freezable include/linux/percpu-rwsem.h:83 [inline] __sb_start_write include/linux/fs/super.h:19 [inline] sb_start_write+0x18e/0x1c0 include/linux/fs/super.h:125 mnt_want_write+0x41/0x90 fs/namespace.c:494 filename_unlinkat+0x148/0x610 fs/namei.c:5562 __do_sys_unlink fs/namei.c:5620 [inline] __se_sys_unlink+0x2e/0x140 fs/namei.c:5617 do_syscall_64+0x174/0x580 arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x77/0x7f This behavior allows an unprivileged user to intentionally trigger a kernel panic by freezing a user namespace mount (like tmpfs or fuse) and attempting to write to it, leading to a local denial of service. Fix this by using TASK_IDLE (which is TASK_UNINTERRUPTIBLE | TASK_NOLOAD) instead of TASK_UNINTERRUPTIBLE when freeze is true. This explicitly tells the hung task watchdog to ignore these tasks, preventing false positive panics while preserving the freeze/thaw mechanics and system suspend capabilities (TASK_FREEZABLE). Since freeze is only true when called from percpu_down_read_freezable() (used exclusively by __sb_start_write()), this change safely and specifically targets tasks waiting on a frozen superblock. Fixes: 559b3bbfa978 ("locking/percpu-rwsem: add freezable alternative to down_read") Assisted-by: Gemini:gemini-3.5-flash Gemini:gemini-3.1-pro-preview syzbot Reported-by: syzbot+b3fba2e269970207b61d@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=b3fba2e269970207b61d Link: https://syzkaller.appspot.com/ai_job?id=1f731a02-676c-4f22-a26c-1ff8c1dd0a49 To: "Boqun Feng" To: To: "Ingo Molnar" To: "Peter Zijlstra" To: "Will Deacon" To: "James Bottomley" Cc: "Waiman Long" --- diff --git a/kernel/locking/percpu-rwsem.c b/kernel/locking/percpu-rwsem.c index f7e152c40..57e24fdc0 100644 --- a/kernel/locking/percpu-rwsem.c +++ b/kernel/locking/percpu-rwsem.c @@ -157,8 +157,7 @@ static void percpu_rwsem_wait(struct percpu_rw_semaphore *sem, bool reader, spin_unlock_irq(&sem->waiters.lock); while (wait) { - set_current_state(TASK_UNINTERRUPTIBLE | - (freeze ? TASK_FREEZABLE : 0)); + set_current_state(freeze ? (TASK_IDLE | TASK_FREEZABLE) : TASK_UNINTERRUPTIBLE); if (!smp_load_acquire(&wq_entry.private)) break; schedule(); base-commit: 075b74841bd0065a3bda3440873c747938e69b68 -- This is an AI-generated patch subject to moderation. Reply with '#syz upstream' to Sign-off the patch as a human author and send it to the upstream kernel mailing lists. Reply with '#syz reject' to reject it ('#syz unreject' to undo). See https://goo.gle/syzbot-ai-patches for information about AI-generated patches. The person who has signed off on the patch is responsible for addressing comments. syzbot engineers can be reached at syzkaller@googlegroups.com.