[PATCH] char/hpet: Fix missing TASK_RUNNING before put_user() in hpet_read()

From: Habil Eren Türker

Date: Sun Sep 27 2026 - 14:41:41 EST


hpet_read() sets the current task state to TASK_INTERRUPTIBLE within
the read loop. However, when data becomes available, it exits the loop
without restoring the TASK_RUNNING state. The subsequent put_user()
operation may go to sleep due to a page fault, which triggers:

do not call blocking ops when !TASK_RUNNING; state=1 set at
[<ffffffff85b6d1eb>] hpet_read+0x21b/0x6a0 drivers/char/hpet.c:285

WARNING: kernel/sched/core.c:9187 at __might_sleep+0x94/0xc0
kernel/sched/core.c:9187, CPU#0: syz.0.873/9126

Call Trace:
__might_fault+0x8b/0x140 mm/memory.c:7480
hpet_read+0x56f/0x6a0 drivers/char/hpet.c:309
do_loop_readv_writev fs/read_write.c:848 [inline]
do_loop_readv_writev fs/read_write.c:836 [inline]
vfs_readv+0x5d8/0x8d0 fs/read_write.c:1021
do_preadv+0x1ac/0x270 fs/read_write.c:1133
do_syscall_x64 arch/x86/entry/syscall_64.c:61 [inline]
do_syscall_64+0x123/0x790 arch/x86/entry/syscall_64.c:84
entry_SYSCALL_64_after_hwframe+0x77/0x7f

Restore TASK_RUNNING before breaking out of the loop.

Reported-by: syzbot+fc3a448093c17a792368@xxxxxxxxxxxxxxxxxxxxxxxxx
Closes: https://syzkaller.appspot.com/bug?extid=fc3a448093c17a792368
Signed-off-by: Habil Eren Türker <habilerenturker@xxxxxxxxxxx>
---
drivers/char/hpet.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c
index 285c60374..7ad319c6d 100644
--- a/drivers/char/hpet.c
+++ b/drivers/char/hpet.c
@@ -290,6 +290,7 @@ hpet_read(struct file *file, char __user *buf, size_t count, loff_t * ppos)
spin_unlock_irq(&hpet_lock);

if (data) {
+ __set_current_state(TASK_RUNNING);
break;
} else if (file->f_flags & O_NONBLOCK) {
retval = -EAGAIN;
--
2.47.3