* BUG: WARNING in dvb_frontend_get_event @ 2023-04-18 4:50 Yu Hao 2023-04-27 7:58 ` Takashi Iwai 0 siblings, 1 reply; 3+ messages in thread From: Yu Hao @ 2023-04-18 4:50 UTC (permalink / raw) To: mchehab, linux-media, linux-kernel Hello, We found the following issue using syzkaller on Linux v6.2.0. In the function `dvb_frontend_get_event`, function `wait_event_interruptible` is called and the condition is `dvb_frontend_test_event(fepriv, events)`. In the function `dvb_frontend_test_event`, function `down(&fepriv->sem);` is called. However, function `wait_event_interruptible` would put the process to sleep. And function `down(&fepriv->sem);` may block the process. So there is the issue with "do not call blocking ops when !TASK_RUNNING". The full report including the Syzkaller reproducer & C reproducer: https://gist.github.com/ZHYfeng/4c5f8be6adc63b73dba68230d15ece2c The brief report is below: Syzkaller hit 'WARNING in dvb_frontend_get_event' bug. ------------[ cut here ]------------ do not call blocking ops when !TASK_RUNNING; state=1 set at [<ffffffff8161186d>] prepare_to_wait_event+0x6d/0x690 kernel/sched/wait.c:333 WARNING: CPU: 0 PID: 8017 at kernel/sched/core.c:9968 __might_sleep+0x10a/0x160 kernel/sched/core.c:9968 Modules linked in: CPU: 0 PID: 8017 Comm: syz-executor303 Not tainted 6.2.0 #1 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.13.0-1ubuntu1.1 04/01/2014 RIP: 0010:__might_sleep+0x10a/0x160 kernel/sched/core.c:9968 Code: 9d 03 00 48 8d bb d8 16 00 00 48 89 fa 48 c1 ea 03 80 3c 02 00 75 34 48 8b 93 d8 16 00 00 48 c7 c7 e0 68 4c 8a e8 38 55 72 08 <0f> 0b e9 75 ff ff ff e8 1a 7b 7f 00 e9 26 ff ff ff 89 34 24 e8 1d RSP: 0018:ffffc9000e537ac8 EFLAGS: 00010282 RAX: 0000000000000000 RBX: ffff888018bdba80 RCX: 0000000000000000 RDX: 0000000000000000 RSI: ffff888018bdba80 RDI: fffff52001ca6f4b RBP: ffffffff8a4cd200 R08: 0000000000000000 R09: ffffed1005944f32 R10: ffff88802ca2798b R11: ffffed1005944f31 R12: 000000000000003a R13: 0000000000000000 R14: 0000000000000000 R15: ffff888044057260 FS: 0000555555995880(0000) GS:ffff88802ca00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007fd34db66000 CR3: 000000001f479000 CR4: 0000000000350ef0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: <TASK> down+0x1e/0xa0 kernel/locking/semaphore.c:58 dvb_frontend_test_event drivers/media/dvb-core/dvb_frontend.c:277 [inline] dvb_frontend_get_event.isra.0+0x528/0x670 drivers/media/dvb-core/dvb_frontend.c:301 dvb_frontend_handle_ioctl+0x1953/0x2ea0 drivers/media/dvb-core/dvb_frontend.c:2726 dvb_frontend_do_ioctl+0x1c5/0x2f0 drivers/media/dvb-core/dvb_frontend.c:2097 dvb_usercopy+0xbe/0x280 drivers/media/dvb-core/dvbdev.c:961 dvb_frontend_ioctl+0x5a/0x80 drivers/media/dvb-core/dvb_frontend.c:2111 vfs_ioctl fs/ioctl.c:51 [inline] __do_sys_ioctl fs/ioctl.c:870 [inline] __se_sys_ioctl fs/ioctl.c:856 [inline] __x64_sys_ioctl+0x198/0x210 fs/ioctl.c:856 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x35/0xb0 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x63/0xcd RIP: 0033:0x7f569e9f4a7d Code: 28 c3 e8 36 29 00 00 66 0f 1f 44 00 00 f3 0f 1e fa 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 c0 ff ff ff f7 d8 64 89 01 48 RSP: 002b:00007fff77694948 EFLAGS: 00000246 ORIG_RAX: 0000000000000010 RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f569e9f4a7d RDX: 0000000020000000 RSI: 0000000080286f4e RDI: 0000000000000003 RBP: 00007f569e9ae440 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000246 R12: 00007f569e9ae4e0 R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000 </TASK> ^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: BUG: WARNING in dvb_frontend_get_event 2023-04-18 4:50 BUG: WARNING in dvb_frontend_get_event Yu Hao @ 2023-04-27 7:58 ` Takashi Iwai 2023-05-04 8:28 ` Takashi Iwai 0 siblings, 1 reply; 3+ messages in thread From: Takashi Iwai @ 2023-04-27 7:58 UTC (permalink / raw) To: Yu Hao; +Cc: mchehab, linux-media, linux-kernel On Tue, 18 Apr 2023 06:50:07 +0200, Yu Hao wrote: > > Hello, > > We found the following issue using syzkaller on Linux v6.2.0. > > In the function `dvb_frontend_get_event`, function > `wait_event_interruptible` is called > and the condition is `dvb_frontend_test_event(fepriv, events)`. > In the function `dvb_frontend_test_event`, function > `down(&fepriv->sem);` is called. > However, function `wait_event_interruptible` would put the process to sleep. > And function `down(&fepriv->sem);` may block the process. > So there is the issue with "do not call blocking ops when !TASK_RUNNING". > > The full report including the Syzkaller reproducer & C reproducer: > https://gist.github.com/ZHYfeng/4c5f8be6adc63b73dba68230d15ece2c FYI, CVE-2023-31084 was assigned to this bug, and I was involved now though distro's bug report. So, the use of semaphore together with wait_event*() macro doesn't look like a good idea. A possible easy workaround would be to open-code the wait loop like below. Mauro, let me know if it's an acceptable workaround. Then I'll submit a proper patch. thanks, Takashi -- 8< -- --- a/drivers/media/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb-core/dvb_frontend.c @@ -293,14 +293,22 @@ static int dvb_frontend_get_event(struct dvb_frontend *fe, } if (events->eventw == events->eventr) { - int ret; + struct wait_queue_entry wait; + int ret = 0; if (flags & O_NONBLOCK) return -EWOULDBLOCK; - ret = wait_event_interruptible(events->wait_queue, - dvb_frontend_test_event(fepriv, events)); - + init_waitqueue_entry(&wait, current); + add_wait_queue(&events->wait_queue, &wait); + while (!dvb_frontend_test_event(fepriv, events)) { + wait_woken(&wait, TASK_INTERRUPTIBLE, 0); + if (signal_pending(current)) { + ret = -ERESTARTSYS; + break; + } + } + remove_wait_queue(&events->wait_queue, &wait); if (ret < 0) return ret; } ^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: BUG: WARNING in dvb_frontend_get_event 2023-04-27 7:58 ` Takashi Iwai @ 2023-05-04 8:28 ` Takashi Iwai 0 siblings, 0 replies; 3+ messages in thread From: Takashi Iwai @ 2023-05-04 8:28 UTC (permalink / raw) To: mchehab; +Cc: Yu Hao, linux-media, linux-kernel On Thu, 27 Apr 2023 09:58:24 +0200, Takashi Iwai wrote: > > On Tue, 18 Apr 2023 06:50:07 +0200, > Yu Hao wrote: > > > > Hello, > > > > We found the following issue using syzkaller on Linux v6.2.0. > > > > In the function `dvb_frontend_get_event`, function > > `wait_event_interruptible` is called > > and the condition is `dvb_frontend_test_event(fepriv, events)`. > > In the function `dvb_frontend_test_event`, function > > `down(&fepriv->sem);` is called. > > However, function `wait_event_interruptible` would put the process to sleep. > > And function `down(&fepriv->sem);` may block the process. > > So there is the issue with "do not call blocking ops when !TASK_RUNNING". > > > > The full report including the Syzkaller reproducer & C reproducer: > > https://gist.github.com/ZHYfeng/4c5f8be6adc63b73dba68230d15ece2c > > FYI, CVE-2023-31084 was assigned to this bug, and I was involved now > though distro's bug report. > > So, the use of semaphore together with wait_event*() macro doesn't > look like a good idea. A possible easy workaround would be to > open-code the wait loop like below. > > Mauro, let me know if it's an acceptable workaround. Then I'll submit > a proper patch. A gentle ping. Can anyone please check whether the suggested change is OK or not? thanks, Takashi > > > thanks, > > Takashi > > -- 8< -- > --- a/drivers/media/dvb-core/dvb_frontend.c > +++ b/drivers/media/dvb-core/dvb_frontend.c > @@ -293,14 +293,22 @@ static int dvb_frontend_get_event(struct dvb_frontend *fe, > } > > if (events->eventw == events->eventr) { > - int ret; > + struct wait_queue_entry wait; > + int ret = 0; > > if (flags & O_NONBLOCK) > return -EWOULDBLOCK; > > - ret = wait_event_interruptible(events->wait_queue, > - dvb_frontend_test_event(fepriv, events)); > - > + init_waitqueue_entry(&wait, current); > + add_wait_queue(&events->wait_queue, &wait); > + while (!dvb_frontend_test_event(fepriv, events)) { > + wait_woken(&wait, TASK_INTERRUPTIBLE, 0); > + if (signal_pending(current)) { > + ret = -ERESTARTSYS; > + break; > + } > + } > + remove_wait_queue(&events->wait_queue, &wait); > if (ret < 0) > return ret; > } ^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2023-05-04 8:32 UTC | newest] Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2023-04-18 4:50 BUG: WARNING in dvb_frontend_get_event Yu Hao 2023-04-27 7:58 ` Takashi Iwai 2023-05-04 8:28 ` Takashi Iwai
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.